Repository navigation
Expand file tree
/
Copy pathgraphics.html
More file actions
1162 lines (1013 loc) · 118 KB
/
Copy pathgraphics.html
File metadata and controls
1162 lines (1013 loc) · 118 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html><html xmlns:dc="http://purl.org/dc/terms/" xmlns:og="http://ogp.me/ns#" ><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><title>Graphics and Music Challenges for Classic-Style Computer Applications</title>
<meta name="citation_pdf_url" content="https://peteroupc.github.io/graphics.pdf">
<meta name="citation_url" content="https://peteroupc.github.io/graphics.html">
<meta name="citation_title" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta name="dc.date" content="2026-11-02">
<meta name="citation_date" content="2026/11/02">
<meta name="citation_publication_date" content="2026/11/02">
<meta name="citation_online_date" content="2026/11/02">
<meta property="og:title" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta property="og:description" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta name="description" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta property="og:type" content="article">
<meta property="og:url" content="https://peteroupc.github.io/graphics.html">
<meta property="og:site_name" content="peteroupc.github.io">
<meta property="og:image" content="https://peteroupc.github.io/graphics.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1056">
<meta property="og:image:height" content="594">
<meta name="dc.format" content="text/html">
<meta name="dc.language" content="en">
<meta name="title" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta name="dc.title" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="peteroupc.github.io">
<meta name="twitter:title" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta name="twitter:url" content="https://peteroupc.github.io/graphics.html">
<meta name="twitter:description" content="Graphics and Music Challenges for Classic-Style Computer Applications">
<meta name="twitter:image" content="https://peteroupc.github.io/graphics.png">
<meta name="twitter:image:width" content="1056">
<meta name="twitter:image:height" content="594">
<meta name="dc.creator" content="Peter Occil"/>
<meta name="author" content="Peter Occil"/>
<meta name="citation_author" content="Peter Occil"/>
<meta name="viewport" content="width=device-width"><link rel=stylesheet type="text/css" href="/style.css">
<script type="text/x-mathjax-config"> MathJax.Hub.Config({"HTML-CSS": { availableFonts: ["STIX","TeX"], linebreaks: { automatic:true }, preferredFont: "TeX" },
tex2jax: { displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], processEscapes: true } });
</script><script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML-full"></script></head><body> <div class="header">
<nav><p><a href="#navigation">Menu</a> - <a href="#top">Top</a> - <a href="/">Home</a></nav></div>
<div class="mainarea" id="top">
<h1 id="graphics-and-music-challenges-for-classic-style-computer-applications">Graphics and Music Challenges for Classic-Style Computer Applications</h1><p>This version of the document is dated 2026-11-02. <a href='https://github.com/peteroupc/peteroupc.github.io/issues'>Post an issue or comment on this document</a>.</p>
<p><a href="mailto:poccil14@gmail.com"><strong>Peter Occil</strong></a></p>
<p>The following are challenges I make to the computer community, relating to:</p>
<ul>
<li><a href="#Graphics_Challenge_for_Classic_Style_Games"><strong>Graphics for classic-style game development</strong></a>.</li>
<li><a href="#Building_a_Public_Domain_music_synthesis_library_and_instrument_banks"><strong>MIDI music synthesis for classic-style games and apps</strong></a>.</li>
<li><a href="https://peteroupc.github.io/classic-wallpaper"><strong>Tileable wallpapers with limited colors and resolution</strong></a>.</li>
<li><a href="#Other_Challenges_and_Projects"><strong>Other challenges and projects</strong></a>.</li>
</ul>
<p>All may interest 1990s computer users.</p>
<p><a id="Contents"></a></p>
<h2 id="contents">Contents</h2>
<ul>
<li><a href="#Contents"><strong>Contents</strong></a></li>
<li><a href="#Graphics_Challenge_for_Classic_Style_Games"><strong>Graphics Challenge for Classic-Style Games</strong></a>
<ul>
<li><a href="#The_Specification"><strong>The Specification</strong></a></li>
<li><a href="#Classic_Graphics_in_Scope"><strong>Classic Graphics in Scope</strong></a></li>
<li><a href="#Optional_Limits"><strong>Optional Limits</strong></a></li>
<li><a href="#Notes_on_Specification"><strong>Notes on Specification</strong></a>
<ul>
<li><a href="#Screen_resolutions"><strong>Screen resolutions</strong></a></li>
<li><a href="#Frame_rate"><strong>Frame rate</strong></a></li>
<li><a href="#3_D_graphics"><strong>3-D graphics</strong></a></li>
<li><a href="#Graphics_in_video_arcade_games"><strong>Graphics in video arcade games</strong></a></li>
<li><a href="#Screen_image_effects_filters"><strong>Screen image effects (filters)</strong></a></li>
<li><a href="#Sounds"><strong>Sounds</strong></a></li>
<li><a href="#Memory"><strong>Memory</strong></a></li>
<li><a href="#Miscellaneous"><strong>Miscellaneous</strong></a></li>
</ul>
</li>
<li><a href="#Seeking_Comments"><strong>Seeking Comments</strong></a></li>
<li><a href="#Further_Reading"><strong>Further Reading</strong></a></li>
</ul>
</li>
<li><a href="#Building_a_Public_Domain_music_synthesis_library_and_instrument_banks"><strong>Building a Public-Domain music synthesis library and instrument banks</strong></a></li>
<li><a href="#Other_Challenges_and_Projects"><strong>Other Challenges and Projects</strong></a>
<ul>
<li><a href="#Classic_desktop_wallpaper"><strong>Classic desktop wallpaper</strong></a></li>
<li><a href="#Button_and_border_styles_for_classic_interfaces"><strong>Button and border styles for classic interfaces</strong></a></li>
<li><a href="#Sound_bank_development_guide"><strong>Sound bank development guide</strong></a></li>
<li><a href="#Guide_for_creating_3_D_models_in_the_pre_2000_style"><strong>Guide for creating 3-D models in the pre-2000 style</strong></a></li>
<li><a href="#Book_form_tutorial_on_pre_2000_computer_graphics_programming"><strong>Book-form tutorial on pre-2000 computer graphics programming</strong></a></li>
</ul>
</li>
<li><a href="#Acknowledgments"><strong>Acknowledgments</strong></a></li>
<li><a href="#License"><strong>License</strong></a></li>
<li><a href="#Notes"><strong>Notes</strong></a></li>
</ul>
<p><a id="Graphics_Challenge_for_Classic_Style_Games"></a></p>
<h2 id="graphics-challenge-for-classic-style-games">Graphics Challenge for Classic-Style Games</h2>
<p>An interesting challenge for game developers, relating to designing games with classic graphics that run on an exceptional variety of modern and recent computers.</p>
<p>In this document, <em>classic graphics</em> or <em>pre-2000 graphics</em> generally means two- or three-dimensional graphics achieved by video games up to some year earlier than 2000, before the advent of programmable “shaders”. For details, see “<a href="#Classic_Graphics_in_Scope"><strong>Classic Graphics in Scope</strong></a>”, later. (To summarize: In general, a game screen of 640 × 480 or smaller, up to 12,800 3-D polygons at a time, and tile- or sprite-based 2-D visuals are involved.)</p>
<p>This challenge is intended to encourage the making of—</p>
<ul>
<li>modern video games that simulate pre-2000 graphics and run with very low resource requirements (say, 64 million bytes of memory or less) and even on very low-end computers (say, those that date from 2010 or earlier or support Windows 7, Windows XP, or even older), and</li>
<li>graphics engines and editors (especially free and open-source ones) devoted to pre-2000 visuals and meant for developing such modern video games.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></li>
</ul>
<p>Most desktop and laptop computers from 2010 on, and most smartphones from 2016 on, can draw even high-quality pre-2000 graphics using only software — without relying on specialized video cards — at 640 × 480 pixels or smaller, screen resolutions typically targeted by video games in the 1990s and earlier.<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup></p>
<p>The challenge sets an <em>upper bound</em> on the kind of computer graphics that are of interest. Further <a href="#Optional_Limits"><strong>constraints to graphics computation</strong></a> (such as memory, resource, color, resolution, or triangle limits) are highly encouraged. It is also encouraged to establish a lean programming interface for this specification; for details, see “<a href="https://peteroupc.github.io/graphicsapi.html"><strong>Lean Programming Interfaces for Classic Graphics</strong></a>”.</p>
<p><a id="The_Specification"></a></p>
<h3 id="the-specification">The Specification</h3>
<p>Limit 3-D graphics to the following:<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup></p>
<ol>
<li>The number of <em>primitives</em> that can be shown at a time (“per frame”)<sup id="fnref:4"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup> is limited (see later in this specification). The number of <em>vertices</em> that can be shown at a time is 3 times the maximum number of primitives.
<ul>
<li>A <em>primitive</em> is a triangle or a line segment. Alternatively, a primitive is a triangle, a line segment, or a convex quadrilateral.</li>
<li>A <em>vertex</em> (plural: <em>vertices</em>) has at least these properties: a three-dimensional position (x-, y-, and z-coordinates) and a <em>vertex color</em> of a format given later. A vertex may also have one or more pairs of <em>texture coordinates</em> (u- and v-coordinates) depending on whether the vertex belongs to a texture-mapped or texture-blended primitive.<sup id="fnref:5"><a href="#fn:5" class="footnote" rel="footnote" role="doc-noteref">5</a></sup></li>
<li>Each vertex of the primitive points to a vertex from the vertex list described later.</li>
</ul>
</li>
<li>Each <em>texture</em> (a rectangular image that is applied to the surface of 3-D objects)—
<ul>
<li>is in a 16-bit-per-pixel format, where each pixel has a vertex color format given later in this specification, or</li>
<li>is in a 1-, 2-, 4-, or 8-bit-per-pixel format and has a table of colors with that color format.</li>
</ul>
</li>
<li>The width and height of each texture are each powers of 2.</li>
<li>For 3-D graphics, any number of the following features are supported:<sup id="fnref:6"><a href="#fn:6" class="footnote" rel="footnote" role="doc-noteref">6</a></sup>
<ul>
<li>Z buffering (depth buffering).</li>
<li>Flat shading.</li>
<li>Gouraud shading.</li>
<li>Per-vertex specular highlighting.</li>
<li>Per-vertex depth-based fog.</li>
<li>3-D line drawing (by approximating the line at integer coordinates).</li>
<li>Two-texture blending.</li>
<li>MIP mapping of textures.</li>
<li>Bilinear filtering of textures.</li>
<li>Edge antialiasing (smoothing)<sup id="fnref:7"><a href="#fn:7" class="footnote" rel="footnote" role="doc-noteref">7</a></sup>.</li>
<li>Perspective correction (outside the vertices)<sup id="fnref:8"><a href="#fn:8" class="footnote" rel="footnote" role="doc-noteref">8</a></sup>.</li>
<li>Alpha blending.<sup id="fnref:9"><a href="#fn:9" class="footnote" rel="footnote" role="doc-noteref">9</a></sup></li>
</ul>
</li>
<li>Only the following color formats are supported for vertex colors:
<ul>
<li>The red, green, and blue components occupy up to 5 bits each. No transparent or translucent pixels.</li>
<li>The red and blue components occupy 5 bits each and the green component occupies 6 bits. No transparent or translucent (semitransparent) pixels.</li>
<li>The red, green, and blue components occupy up to 5 bits each. A 1-bit alpha component marks transparent pixels. No translucent pixels.</li>
<li>For 3-D rendering only: The red, green, and blue components occupy 4 bits each, and a 4-bit alpha component marks transparent and translucent pixels. (Translucent pixels enable alpha blending.)</li>
</ul>
</li>
</ol>
<p>Limit 2-D graphics to the following:<sup id="fnref:10"><a href="#fn:10" class="footnote" rel="footnote" role="doc-noteref">10</a></sup></p>
<ol>
<li>Layers:
<ol>
<li>Up to four <em>2-D layers</em> can be displayed at a time. Each 2-D layer is a rectangular array of references to <em>tiles</em> (see later), and can also be called a <em>tile map</em>.<sup id="fnref:11"><a href="#fn:11" class="footnote" rel="footnote" role="doc-noteref">11</a></sup></li>
<li>If 3-D graphics are being displayed, one of the 2-D layers is replaced with a <em>3-D layer</em>, which is an image on which the 3-D graphics are drawn. Which 2-D layer is replaced this way can vary over time.</li>
<li>The 2-D layers may contain transparent pixels. The 3-D layer may contain transparent and translucent (semitransparent) pixels.</li>
<li>The upper-left corner of a 2-D layer can be placed anywhere relative to the game screen and even outside it. The 3-D layer’s upper-left corner and dimensions are the same as the game screen image’s.</li>
</ol>
</li>
<li>Tiles. A <em>tile</em> is a small rectangular array of pixels.
<ol>
<li>Tiles share width in pixels, height in pixels, and number of bits per pixel.</li>
<li>If tiles have fewer than 8 bits per pixel, each tile uses one of 16 color tables. If tiles have 8 bits per pixel, they use the same 256-color table.</li>
<li>Each color in each color table used by tiles is of a vertex color format given earlier.</li>
</ol>
</li>
<li>Sprites. A <em>sprite</em> is a rectangular array of either tiles or pixels.
<ol>
<li>Each sprite made of pixels (rather than tiles) has a pixel format allowed for textures, given earlier.</li>
<li>Each sprite can be drawn above or below any of the 2-D or 3-D layers.</li>
<li>The upper-left corner of a sprite can be placed anywhere relative to the game screen and even outside it.</li>
</ol>
</li>
<li>The drawing of sprites and tiles with transparency (that is, the drawing of some or all of their pixels) is supported.<sup id="fnref:12"><a href="#fn:12" class="footnote" rel="footnote" role="doc-noteref">12</a></sup> Sprites and tiles with translucent (semitransparent) pixels are not supported, and drawing sprites and tiles with translucency is also not supported.</li>
</ol>
<p>Other requirements:</p>
<ul>
<li><strong>Rendering in software:</strong> The game includes a mode in which the graphics are <em>rendered in software</em>. This means that their rendering does not rely on a video card or graphics accelerator, whether directly or indirectly (such as through GDI, OpenGL, or Direct3D), with the sole exception of sending a finished game screen image to the player’s display (such as through GDI’s <code>StretchDIBits</code> or copying to video memory). (Implementing a subset of <a href="https://registry.khronos.org/OpenGL/index_es.php"><strong>OpenGL ES</strong></a> 1.1 or <a href="https://registry.khronos.org/OpenGL/index_gl.php"><strong>OpenGL</strong></a> 1.1 in software without relying on a video card or graphics accelerator is allowed.) The game can optionally support hardware acceleration of graphics as well (and can even use such acceleration by default when the game detects its availability).</li>
<li><strong>Music:</strong> Music is in the Standard MIDI File (SMF) format only.<sup id="fnref:13"><a href="#fn:13" class="footnote" rel="footnote" role="doc-noteref">13</a></sup></li>
</ul>
<p>The following are decided by the application:</p>
<ol>
<li>The <strong>“screen resolution”</strong>: the width and height of the game screen image in pixels. The game screen image has no more than 307,200 total pixels (that is, no more pixels than a 640-×-480 screen, or a screen with 640 pixels horizontally and 480 vertically).<sup id="fnref:14"><a href="#fn:14" class="footnote" rel="footnote" role="doc-noteref">14</a></sup></li>
<li>
<p>If 3-D is supported:</p>
<ol>
<li>The maximum number of primitives shown simultaneously (“per frame”)<sup id="fnref:4:1"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup>. This number is no more than screen width times screen height divided by 24. (Thus, the number of vertices per frame is no more than screen width times screen height divided by 8. See examples later in this specification.)</li>
<li>Whether convex quadrilaterals (in addition to triangles and line segments) are 3-D primitives for purposes of the primitive limits.</li>
<li>Which 3-D features are supported, as given in point 5 of the 3-D graphics section (for example, Gouraud shading, perspective correction, line drawing). (This can also be expressed as a subset of OpenGL 1.1 or OpenGL ES 1.1 that the application implements.)</li>
<li>The maximum width and height of a texture in pixels. Each is no more than 256 and no more than the larger of the screen width and the screen height.</li>
<li>Whether translucent pixels, transparent pixels, or both are supported in vertices and textures.</li>
</ol>
</li>
<li>
<p>If 2-D tiles and sprites are supported:</p>
<ol>
<li>The number of 2-D layers (up to four).</li>
<li>The number of bits per pixel that tiles have: 1, 2, 4, or 8.</li>
<li>The width and height of each tile, in pixels. The width is no more than 32, and the height is no more than 32.<sup id="fnref:15"><a href="#fn:15" class="footnote" rel="footnote" role="doc-noteref">15</a></sup></li>
<li>The maximum width and maximum height of a sprite in pixels. Each is no more than the following: Take the larger of the screen width and screen height, then divide by 4, then round up to the nearest power of 2.</li>
<li>The maximum number of sprites displayed at a time on the game screen, no more than (screen width × screen height) / 256, rounded up.<sup id="fnref:16"><a href="#fn:16" class="footnote" rel="footnote" role="doc-noteref">16</a></sup></li>
<li>Whether sprites made of tiles, sprites made of pixels, or both are supported.</li>
</ol>
</li>
</ol>
<p>The following are optional features; the application decides:</p>
<ol>
<li>Whether the application supports game screen resolutions with more pixels than a 640-×-480 screen, in addition to the primary resolution.</li>
<li>Whether hardware acceleration is supported in addition to rendering in software.</li>
<li>Whether tiles can be flipped horizontally and/or vertically.</li>
<li>Whether sprites can undergo a 2-D affine transformation (such as a rotation, enlargement, or shrinking).</li>
<li>Whether sprites can be flipped horizontally and/or vertically (even if affine transformation of sprites isn’t supported in general).<sup id="fnref:17"><a href="#fn:17" class="footnote" rel="footnote" role="doc-noteref">17</a></sup></li>
<li>Whether at least one of the 2-D layers can undergo a 2-D affine transformation.</li>
</ol>
<p> </p>
<blockquote>
<p><strong>Notes:</strong></p>
<ol>
<li>
<p>The following are recommended for this challenge:</p>
<ol>
<li>Image files used by the game should not store “pre-pixelated” textures, sprites, or tiles. A “pre-pixelated” image results when an image is enlarged in advance with point filtering (also called point sampling or nearest-neighbor filtering), with the result that some or all of the resulting image’s rows and columns are repeated.</li>
<li>The game should use graphics and sound routines that implement the specification in software, are portable to diverse platforms, and have a minimum of code.</li>
<li>The General MIDI System level 1 should be followed for the game’s music files.<sup id="fnref:13:1"><a href="#fn:13" class="footnote" rel="footnote" role="doc-noteref">13</a></sup></li>
</ol>
</li>
<li>For years earlier than 1999, some of the 3-D features mentioned in the specification (such as texture blending or alpha blending) might not be typical.</li>
<li>As given later in this document, a default screen resolution of 800 × 600 and a limit of, say, 60,000 primitives per frame would be beyond the spirit of this specification. But that resolution and limit (together with a target rate of 60 frames per second) can still serve as a “stress test” for any software renderer seeking to implement this specification.</li>
</ol>
<p><strong>Examples:</strong></p>
<ol>
<li>
<p>The following limits apply for various game screen resolutions. An application can decide on lower limits than the ones shown.</p>
<table>
<thead>
<tr>
<th>Resolution</th>
<th>Max. primitives per frame</th>
<th>Max. vertices per frame</th>
<th>Max. texture size</th>
<th>Max. sprite size</th>
<th>Max. sprites</th>
</tr>
</thead>
<tbody>
<tr>
<td>640 × 480</td>
<td>12800</td>
<td>38400</td>
<td>256 × 256</td>
<td>256 × 256</td>
<td>1200</td>
</tr>
<tr>
<td>256 × 192</td>
<td>2048</td>
<td>6144</td>
<td>256 × 256</td>
<td>64 × 64</td>
<td>192</td>
</tr>
<tr>
<td>320 × 200</td>
<td>2666</td>
<td>8000</td>
<td>256 × 256</td>
<td>128 × 128</td>
<td>250</td>
</tr>
<tr>
<td>320 × 240</td>
<td>3200</td>
<td>9600</td>
<td>256 × 256</td>
<td>128 × 128</td>
<td>300</td>
</tr>
<tr>
<td>512 × 384</td>
<td>8192</td>
<td>24576</td>
<td>256 × 256</td>
<td>128 × 128</td>
<td>768</td>
</tr>
<tr>
<td>480 × 360</td>
<td>7200</td>
<td>21600</td>
<td>256 × 256</td>
<td>128 × 128</td>
<td>675</td>
</tr>
<tr>
<td>640 × 360</td>
<td>9600</td>
<td>28800</td>
<td>256 × 256</td>
<td>256 × 256</td>
<td>900</td>
</tr>
<tr>
<td>640 × 400</td>
<td>10666</td>
<td>32000</td>
<td>256 × 256</td>
<td>256 × 256</td>
<td>1000</td>
</tr>
</tbody>
</table>
</li>
<li>
<p>For the screen resolution 640 × 480 and a frame rate of 60 frames per second, the maximum number of primitives per second is 768,000 (= 60 × (640 × 480) / 24); for 320 × 240, it is 192,000.</p>
</li>
<li>
<p>The following is one way to implement the 3-D portion of this specification:</p>
<ul>
<li>Game screen resolution: 512 × 384.</li>
<li>Primitives per frame: up to 5000. Primitives are triangles and line segments, not quadrilaterals.</li>
<li>Maximum texture size: 128 × 128.</li>
<li>Implements a subset of OpenGL ES 1.1, rendered in software.</li>
<li>Has a game engine that renders only in that subset of OpenGL ES 1.1.</li>
<li>No translucent or transparent pixels.</li>
</ul>
</li>
<li>
<p>One way to implement the 2-D limits is: Screen resolution 640 × 480; four 2-D layers; tiles have 4 bits per pixel; tiles are 16 × 16 pixels; maximum sprite size 64x64 pixels; up to 192 sprites at a time; sprites are made of pixels.</p>
</li>
</ol>
</blockquote>
<p><a id="Classic_Graphics_in_Scope"></a></p>
<h3 id="classic-graphics-in-scope">Classic Graphics in Scope</h3>
<p>This specification for “classic graphics”<sup id="fnref:18"><a href="#fn:18" class="footnote" rel="footnote" role="doc-noteref">18</a></sup> in modern games largely reflects the visual limitations of—</p>
<ul>
<li>consumer PCs (personal computers) and other home computers released before 2000 (see example 1 later in this section),<sup id="fnref:19"><a href="#fn:19" class="footnote" rel="footnote" role="doc-noteref">19</a></sup></li>
<li>game consoles (handheld and for TVs) released before 2000,</li>
<li>arcade machines with similar performance to machines described earlier,<sup id="fnref:20"><a href="#fn:20" class="footnote" rel="footnote" role="doc-noteref">20</a></sup></li>
<li>videotex protocols before 1995,<sup id="fnref:21"><a href="#fn:21" class="footnote" rel="footnote" role="doc-noteref">21</a></sup></li>
<li>personal digital assistants, palmtop PCs, graphical calculators, learning toys with an electronic display, and mobile phones with similar performance to consumer PCs from before 2000 (see example 2 later in this section), and</li>
<li>the Game Boy Advance and Nintendo DS, both of which were released after 2000 but have relatively meager graphical ability.</li>
</ul>
<p>Video games and other software programs released in 2000 or later are out of scope, even if they were designed for hardware that launched before 2000. The exceptions are:</p>
<ul>
<li>Video games released before 2010 for the Nintendo DS or the Game Boy Advance.</li>
<li>Video games released before 2007 for personal digital assistants, graphical calculators, learning toys, and mobile phones that do not exceed the performance of consumer PCs released before 2000. See example 2 later in this section.</li>
</ul>
<p>NVIDIA GeForce 256 (late 1999) is out of scope. Some arcade machines, such as SEGA Model 3 (1996) and SEGA NAOMI (1998), may have 3-D features beyond what is “classic” here. Video games released in 1998 or 1999 for Dreamcast (1998) are borderline cases; they are at most barely within the spirit of this challenge.<sup id="fnref:22"><a href="#fn:22" class="footnote" rel="footnote" role="doc-noteref">22</a></sup></p>
<blockquote>
<p><strong>Examples:</strong></p>
<ol>
<li>
<p>In general, PC applications that feature classic graphics include:</p>
<ul>
<li>Windows applications written for DirectX versions earlier than 7 and using Direct3D or DirectDraw for their visuals.</li>
<li>Windows games using GDI or <a href="https://www.pcgamingwiki.com/wiki/List_of_WinG_games"><strong>WinG</strong></a> for graphics and supporting Windows 98 or earlier. Examples are <em>Chip’s Challenge</em> for Windows (1992) and Brian Goble’s <em>The Adventures of MicroMan</em> (1993).</li>
<li>Games for MS-DOS or PC-9801 that were published before 2000. Examples are <em>Quake</em> (1996), <em>WarCraft</em> (1994), and the first titles of the Touhou Project series (1997-1998).</li>
<li>Games using <a href="https://registry.khronos.org/OpenGL/index_gl.php"><strong>OpenGL</strong></a> 1.2 or earlier for graphics.<sup id="fnref:23"><a href="#fn:23" class="footnote" rel="footnote" role="doc-noteref">23</a></sup></li>
<li>So-called “multimedia titles” from the 1990s, or applications resembling interactive versions of books (generally reference and other nonfiction works), complete with sound, animation, and video. See “Multimedia PC Level 1 and Level 2 Specifications” by the Multimedia PC Marketing Council.</li>
</ul>
</li>
<li>
<p>In general, video games covered by the phone exception include games released before 2007 for:</p>
<ul>
<li>The <a href="https://dench.flatlib.jp/app/chiraks_em"><strong>Sharp MI-Zaurus</strong></a> (2000).</li>
<li>Symbian OS.</li>
<li>Mobile phones, palmtop PCs, and personal digital assistants running Windows CE 5.0 or earlier, including when the graphics are drawn using <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa452478%28v=msdn.10%29"><strong>Direct3D Mobile</strong></a>.</li>
<li>Mobile phones, when the graphics are drawn using:
<ul>
<li>Java Micro Edition, its Mobile Information Device Profile (MIDP, <a href="https://jcp.org/en/jsr/detail?id=37"><strong>Java specification request 37</strong></a> and <a href="https://jcp.org/en/jsr/detail?id=118"><strong>JSR 118</strong></a>), or extensions (especially <a href="https://jcp.org/en/jsr/detail?id=184"><strong>JSR 184, Mobile 3D Graphics API</strong></a>). Or…</li>
<li><a href="https://registry.khronos.org/OpenGL/index_es.php"><strong>OpenGL ES</strong></a> 1.1 or 1.0 specification (either the Common profile or the Common-Lite profile with fixed-point but not floating-point arithmetic).</li>
</ul>
</li>
</ul>
<p>If there is interest, this exception could expand to the years 2007 and 2008 and thus include certain video games for the original iPhone from 2007.<sup id="fnref:24"><a href="#fn:24" class="footnote" rel="footnote" role="doc-noteref">24</a></sup></p>
</li>
</ol>
</blockquote>
<p>One of the following games can be considered an upper limit to what is considered “classic graphics” in this specification.</p>
<ul>
<li><em>Quake III Arena</em> (December 1999), which <a href="https://www.dosdays.co.uk/topics/early_3d_games.php"><strong>required DirectX 7 and at least 64 million bytes of memory</strong></a>.</li>
<li><em>Falcon 4.0</em> (1998).</li>
</ul>
<p><a id="Optional_Limits"></a></p>
<h3 id="optional-limits">Optional Limits</h3>
<p>A game may impose further constraints to <a href="#The_Specification"><strong>this specification</strong></a> (for example, to reduce the maximum number of 3-D triangles, to disallow 3-D graphics, to reduce the number of colors per tile allowed, or to <a href="https://peteroupc.github.io/classic-wallpaper/docs/palettes.html"><strong>reduce to a limited set the colors</strong></a> ultimately displayed on screen). I would be interested in knowing about these limitations that a new game that adopts this document decides to impose.</p>
<p>Examples of optional constraints are the following:</p>
<ul>
<li>The game displays no more than 16 colors at a time.<sup id="fnref:25"><a href="#fn:25" class="footnote" rel="footnote" role="doc-noteref">25</a></sup></li>
<li>The game is limited to the 16 colors of the so-called <em>VGA palette</em>: <span style="background:rgb(0,0,0);border:1px black"> </span><span style="background:rgb(128,0,0);border:1px black"> </span><span style="background:rgb(0,128,0);border:1px black"> </span><span style="background:rgb(128,128,0);border:1px black"> </span><span style="background:rgb(0,0,128);border:1px black"> </span><span style="background:rgb(128,0,128);border:1px black"> </span><span style="background:rgb(0,128,128);border:1px black"> </span><span style="background:rgb(128,128,128);border:1px black"> </span><span style="background:rgb(192,192,192);border:1px black"> </span><span style="background:rgb(255,0,0);border:1px black"> </span><span style="background:rgb(0,255,0);border:1px black"> </span><span style="background:rgb(255,255,0);border:1px black"> </span><span style="background:rgb(0,0,255);border:1px black"> </span><span style="background:rgb(255,0,255);border:1px black"> </span><span style="background:rgb(0,255,255);border:1px black"> </span><span style="background:rgb(255,255,255);border:1px black"> </span>.
<ul>
<li>In the 8-bit-per-component color format, this palette’s colors are: light gray, that is, (192, 192, 192); or each color component is 0 or 255; or each color component is 0 or 128.</li>
<li>In the vertex color format, the closest colors to this palette are: 24/24/24; or each color component is 0 or 16; or each color component is 0 or 31.</li>
</ul>
</li>
<li>The game displays no more than 256 colors at a time.<sup id="fnref:26"><a href="#fn:26" class="footnote" rel="footnote" role="doc-noteref">26</a></sup></li>
<li>The game is limited to a fixed set of 236 colors plus black and white.</li>
<li>The game is limited to a fixed set of 256 colors, of which one is black and another is white.</li>
<li>Drawing graphics with translucency (semitransparency) is not supported.</li>
<li>All game files can be packaged in a ZIP file or Win32 program file that takes no more than—
<ul>
<li>1,457,664 bytes (the capacity of a <a href="https://fitsonafloppy.com/"><strong>file-allocation-table (FAT) formatted high-density 3.5-inch floppy disk</strong></a>),<sup id="fnref:27"><a href="#fn:27" class="footnote" rel="footnote" role="doc-noteref">27</a></sup> or</li>
<li>1,213,952 bytes (the capacity of a FAT formatted high-density 5.25-inch floppy disk),<sup id="fnref:27:1"><a href="#fn:27" class="footnote" rel="footnote" role="doc-noteref">27</a></sup> or</li>
<li>730,112 bytes (the capacity of a FAT formatted normal-density 3.5-inch floppy disk),<sup id="fnref:27:2"><a href="#fn:27" class="footnote" rel="footnote" role="doc-noteref">27</a></sup> or</li>
<li>362,496 bytes (the capacity of a FAT formatted double-density 5.25-inch floppy disk),<sup id="fnref:27:3"><a href="#fn:27" class="footnote" rel="footnote" role="doc-noteref">27</a></sup> or</li>
<li>65,536 bytes,<sup id="fnref:28"><a href="#fn:28" class="footnote" rel="footnote" role="doc-noteref">28</a></sup> or</li>
<li>681 million bytes (slightly less than the maximum total size of files in a formatted CD-ROM).<sup id="fnref:29"><a href="#fn:29" class="footnote" rel="footnote" role="doc-noteref">29</a></sup></li>
</ul>
</li>
<li>The game uses no more than 16 million bytes of system memory at a time.</li>
<li>The game uses no more than 655,360 bytes of system memory (plus 262,144 bytes of additional memory for graphical use only) at a time.<sup id="fnref:30"><a href="#fn:30" class="footnote" rel="footnote" role="doc-noteref">30</a></sup></li>
<li>The game is a Win32 application compatible with Windows XP.</li>
<li>The game is a Win32 application compatible with Windows 98.</li>
<li>The game aims for a rate of 30 frames per second.</li>
<li>The game’s graphics must be <em>rendered in software</em> (see specification).</li>
<li>The game’s rendering of visuals employs only 32-bit and smaller integers, integer arithmetic, and fixed-point arithmetic.<sup id="fnref:31"><a href="#fn:31" class="footnote" rel="footnote" role="doc-noteref">31</a></sup></li>
<li>The game’s rendering of visuals employs only 32-bit and smaller integers, integer arithmetic, fixed-point arithmetic, and arithmetic involving 32-bit floating-point numbers (IEEE 754 binary32, or the commonly implemented meaning of the C language’s <code>float</code> type).<sup id="fnref:32"><a href="#fn:32" class="footnote" rel="footnote" role="doc-noteref">32</a></sup></li>
<li>The game renders only white line segments on a black background (or vice versa), and displays no more than 600 of those segments at a time. These line segments are drawn with an approximation at integer coordinates.</li>
<li>The game runs with acceptable performance on <a href="https://www.dosdays.co.uk/topics/cpus.php#i486"><strong>80486-compatible processors</strong></a> at 33 or 50 megahertz.<sup id="fnref:33"><a href="#fn:33" class="footnote" rel="footnote" role="doc-noteref">33</a></sup></li>
<li>The game runs with acceptable performance on x86 processors at 100 megahertz.</li>
</ul>
<p><a id="Notes_on_Specification"></a></p>
<h3 id="notes-on-specification">Notes on Specification</h3>
<p>This section has notes on this specification, such as how its requirements correspond to the graphics abilities of pre-2000 video games.</p>
<p><a id="Screen_resolutions"></a></p>
<h4 id="screen-resolutions">Screen resolutions</h4>
<ul>
<li>
<p>Screen resolutions with more pixels than a 640-×-480 screen (such as 800 × 600) are not within the spirit of this challenge, even though more demanding games in the late 1990s, as well as the <em>PC 98 System Design Guide</em> (1997), aimed for the 800 × 600 resolution or higher for 3-D graphics. Indeed, for the most part, major game consoles and arcade machines in the 1990s and earlier supported resolutions with no more pixels than a 640-×-480 screen.<sup id="fnref:34"><a href="#fn:34" class="footnote" rel="footnote" role="doc-noteref">34</a></sup></p>
</li>
<li>
<p>Screen resolutions that have been used in classic games include:<sup id="fnref:35"><a href="#fn:35" class="footnote" rel="footnote" role="doc-noteref">35</a></sup></p>
<ul>
<li>Video graphics array (VGA) display modes: 640 × 480,<sup id="fnref:36"><a href="#fn:36" class="footnote" rel="footnote" role="doc-noteref">36</a></sup> 320 × 240,<sup id="fnref:37"><a href="#fn:37" class="footnote" rel="footnote" role="doc-noteref">37</a></sup> 320 × 200.<sup id="fnref:38"><a href="#fn:38" class="footnote" rel="footnote" role="doc-noteref">38</a></sup></li>
<li>4:3 aspect ratio: 640 × 480,<sup id="fnref:36:1"><a href="#fn:36" class="footnote" rel="footnote" role="doc-noteref">36</a></sup> 512 × 384,<sup id="fnref:39"><a href="#fn:39" class="footnote" rel="footnote" role="doc-noteref">39</a></sup> 400 × 300,<sup id="fnref:40"><a href="#fn:40" class="footnote" rel="footnote" role="doc-noteref">40</a></sup> 320 × 240,<sup id="fnref:37:1"><a href="#fn:37" class="footnote" rel="footnote" role="doc-noteref">37</a></sup> 256 × 192,<sup id="fnref:41"><a href="#fn:41" class="footnote" rel="footnote" role="doc-noteref">41</a></sup> 160 × 120.<sup id="fnref:42"><a href="#fn:42" class="footnote" rel="footnote" role="doc-noteref">42</a></sup></li>
<li>Game console aspect ratios: 320 × 224,<sup id="fnref:43"><a href="#fn:43" class="footnote" rel="footnote" role="doc-noteref">43</a></sup> 256 × 224,<sup id="fnref:44"><a href="#fn:44" class="footnote" rel="footnote" role="doc-noteref">44</a></sup> 256 × 240,<sup id="fnref:45"><a href="#fn:45" class="footnote" rel="footnote" role="doc-noteref">45</a></sup> 240 × 160,<sup id="fnref:46"><a href="#fn:46" class="footnote" rel="footnote" role="doc-noteref">46</a></sup> 160 × 144.<sup id="fnref:47"><a href="#fn:47" class="footnote" rel="footnote" role="doc-noteref">47</a></sup></li>
<li>5:4 aspect ratio:<sup id="fnref:48"><a href="#fn:48" class="footnote" rel="footnote" role="doc-noteref">48</a></sup> 320 × 256,<sup id="fnref:49"><a href="#fn:49" class="footnote" rel="footnote" role="doc-noteref">49</a></sup></li>
<li>Two-color graphics: 720 × 348,<sup id="fnref:50"><a href="#fn:50" class="footnote" rel="footnote" role="doc-noteref">50</a></sup> 640 × 200,<sup id="fnref:51"><a href="#fn:51" class="footnote" rel="footnote" role="doc-noteref">51</a></sup> 512 × 342.<sup id="fnref:52"><a href="#fn:52" class="footnote" rel="footnote" role="doc-noteref">52</a></sup></li>
<li>Enhanced Graphics Adapter aspect ratio: 640 × 350.<sup id="fnref:53"><a href="#fn:53" class="footnote" rel="footnote" role="doc-noteref">53</a></sup></li>
<li>8:5 aspect ratio: 640 × 400,<sup id="fnref:54"><a href="#fn:54" class="footnote" rel="footnote" role="doc-noteref">54</a></sup> 320 × 200.<sup id="fnref:38:1"><a href="#fn:38" class="footnote" rel="footnote" role="doc-noteref">38</a></sup></li>
<li>Other: 280 × 192,<sup id="fnref:55"><a href="#fn:55" class="footnote" rel="footnote" role="doc-noteref">55</a></sup> 480 × 272,<sup id="fnref:56"><a href="#fn:56" class="footnote" rel="footnote" role="doc-noteref">56</a></sup> 512 × 424, <sup id="fnref:57"><a href="#fn:57" class="footnote" rel="footnote" role="doc-noteref">57</a></sup> 400 × 240,<sup id="fnref:58"><a href="#fn:58" class="footnote" rel="footnote" role="doc-noteref">58</a></sup> 384 × 224,<sup id="fnref:59"><a href="#fn:59" class="footnote" rel="footnote" role="doc-noteref">59</a></sup> 160 × 200,<sup id="fnref:60"><a href="#fn:60" class="footnote" rel="footnote" role="doc-noteref">60</a></sup> 480 × 240.<sup id="fnref:61"><a href="#fn:61" class="footnote" rel="footnote" role="doc-noteref">61</a></sup></li>
</ul>
<p>This is not a complete list. Some game consoles, such as the Nintendo 64, allowed games to alter the screen resolution during gameplay. <a href="#Graphics_in_arcade_video_games"><strong>Arcade game graphics</strong></a> are described later.</p>
</li>
<li>
<p>As of November 1996, “[s]urveys indicate[d] that the great majority of [PC] users operate[d] in 640[ × ]480 resolution with 256 colors”.<sup id="fnref:62"><a href="#fn:62" class="footnote" rel="footnote" role="doc-noteref">62</a></sup></p>
</li>
<li>
<p>A game can support—</p>
<ul>
<li>multiple sizes for the area of the screen where the game’s action is drawn, or</li>
<li>pixel-column or -row doubling as a “quality” setting,</li>
</ul>
<p>or both features, without changing the size of the game’s image. For example, the original <em>Doom</em> (1993) supported several sizes of this kind (on PC, they were 96 × 48, 128 × 64, 160 × 80, and so on up to 288 × 144, as well as 320 × 168 and 320 × 200) and optional pixel-column doubling.<sup id="fnref:63"><a href="#fn:63" class="footnote" rel="footnote" role="doc-noteref">63</a></sup></p>
</li>
<li>
<p>Games within the scope of this challenge are meant to be run in a desktop window if the player’s display is 800 × 600 pixels or larger. The same is true if the game’s resolution is 620 × 420 or smaller and the player’s display is 640 × 480. The game may also support full-screen display.</p>
</li>
<li>
<p>For games that simulate the resolution of video game consoles supporting NTSC- or PAL-compatible TV screens,<sup id="fnref:64"><a href="#fn:64" class="footnote" rel="footnote" role="doc-noteref">64</a></sup> a vertical resolution of—</p>
<ul>
<li>240 or 288 rows of video (respectively) in <em>progressive scan</em> at nearly 60 frames or 50 frames per second, or</li>
<li>480 or 576 rows of <em>interlaced video</em> (in two passes, each pass drawing every other row) at nearly 30 frames or 25 frames per second,</li>
</ul>
<p>is common. (By contrast, the horizontal resolution could vary in such cases.) Such TV screens draw 240 or 288 visible rows from top to bottom, whether in interlacing or progressive scan. In the case of some NTSC-compatible TVs, though, the upper and lower portions of the image are hidden by the bezel, so that, in effect, only 224 rows in progressive scan or 448 rows of interlaced video may be visible (see Rodrigo Copetti’s “Architecture of Consoles” series).</p>
</li>
</ul>
<p><a id="Frame_rate"></a></p>
<h4 id="frame-rate">Frame rate</h4>
<ul>
<li>No particular frame rate is required.<sup id="fnref:65"><a href="#fn:65" class="footnote" rel="footnote" role="doc-noteref">65</a></sup></li>
<li>Possible choices for the frame rate include 20, 30, 40, and 60 frames per second. Rates beyond 60 were rare before 2000.<sup id="fnref:66"><a href="#fn:66" class="footnote" rel="footnote" role="doc-noteref">66</a></sup></li>
<li>For NTSC- and PAL-compatible TV screens, see the remark on frames per second in the previous section.</li>
<li><em>Doom</em> (1993) operated at 35 frames per second but could not be run at that rate (under default settings) by typical PCs of the time.<sup id="fnref:63:1"><a href="#fn:63" class="footnote" rel="footnote" role="doc-noteref">63</a></sup></li>
<li>For comfort reasons, a minimum frame rate may be required for video games that offer “<a href="https://www.pcgamingwiki.com/wiki/Glossary:Native_3D"><strong>3-D vision</strong></a>” by rendering multiple views of the scene at a time, in conjunction with special glasses (for example, a SEGA Master System accessory) or a virtual-reality headset (for example, Nintendo’s Virtual Boy). But such games were rare before 2000.</li>
</ul>
<p><a id="3_D_graphics"></a></p>
<h4 id="d-graphics">3-D graphics</h4>
<ul>
<li>The <em>PC 2001 System Design Guide</em>, <em>PC 99 System Design Guide</em>, <em>PC 98 System Design Guide</em>, and <em>PC 97 Hardware Design Guide</em> gave guidelines for PC 3-D graphics hardware.<sup id="fnref:67"><a href="#fn:67" class="footnote" rel="footnote" role="doc-noteref">67</a></sup> Of these guides, the <em>PC 2001 System Design Guide</em> reflected the “current state of the industry” for such hardware as of 2000. (By contrast, neither the PC 95 Guide nor its supplement has requirements for 3-D hardware acceleration.)</li>
<li>This specification allows for:
<ul>
<li>Prerendered graphics, to simulate showing highly detailed imagery. The following are examples:
<ul>
<li><em>Space Quest V</em> (1993).</li>
<li><em>Myst</em> (1993).</li>
<li><a href="https://www.retro-gamers.it/en/features/star-wars-rebel-assault-cd-rom-spectacle/"><strong><em>Star Wars: Rebel Assault</em></strong></a> (1993).</li>
<li><em>Resident Evil</em> for PlayStation (1996) employed prerendered backgrounds largely due to technical limitations<sup id="fnref:68"><a href="#fn:68" class="footnote" rel="footnote" role="doc-noteref">68</a></sup>.</li>
<li>The original <em>Final Fantasy VII</em> on PlayStation (1997) features prerendered video backgrounds for some of its playable scenes.</li>
<li>The arcade games <em>GP World</em> (1984) and <em>Dragon’s Lair</em> (1983) depict their action in the form of full-motion video.</li>
<li><em>Doom</em> (1993) and <em>Duke Nukem 3D</em> (1996) have 2-D sprites based on real or digital 3-D models.</li>
<li><a href="https://mavorsrants.blogspot.com/2012/04/total-annihilation-graphics-engine.html"><strong><em>Total Annihilation</em></strong></a> (1997) includes 3-D models, but renders them in advance and caches the resulting images to 2-D sprites.</li>
</ul>
</li>
<li>Drawing a 3-D graphic as a <em>voxel model</em> (formed from point samples in 3-D, rather than 2-D, called <em>voxels</em>)<sup id="fnref:69"><a href="#fn:69" class="footnote" rel="footnote" role="doc-noteref">69</a></sup>, as long as the model is rendered in software. But drawing voxel models as polygon meshes is subject to the limits on the number of primitives and vertices.</li>
</ul>
</li>
<li>Stencil buffers<sup id="fnref:70"><a href="#fn:70" class="footnote" rel="footnote" role="doc-noteref">70</a></sup>, bump mapping, and three- or four-texture blending are considered borderline pre-2000 graphics capabilities.<sup id="fnref:71"><a href="#fn:71" class="footnote" rel="footnote" role="doc-noteref">71</a></sup> Supporting these features is optional.</li>
<li>The following are not within the spirit of this challenge:
<ul>
<li>Displaying more than 20,000 triangles at a time (per frame), even for higher screen resolutions. Most 3-D video games before 2000 displayed well fewer than that, but there may be exceptions.<sup id="fnref:22:1"><a href="#fn:22" class="footnote" rel="footnote" role="doc-noteref">22</a></sup> Moreover, a rate of much more than 20,000 triangles per frame is poorly suited for rendering in software.</li>
<li>
<p>Phong shading (per-pixel specular highlighting), ray tracing, and path tracing, which were too slow for real-time use in the 20th century. Exceptions include:</p>
<ol>
<li>Per-screen-column <em>ray casting</em>, of the kind popularized in <em>Wolfenstein 3-D</em> (1992).<sup id="fnref:72"><a href="#fn:72" class="footnote" rel="footnote" role="doc-noteref">72</a></sup></li>
<li><em>Light maps</em> with precomputed lighting (for example, Abrash 2007, chapters 68 and 69).</li>
</ol>
<p>Phong shading is not to be confused with the Phong lighting model; per-vertex lighting in software using the Phong lighting model is allowed.</p>
</li>
</ul>
</li>
<li>It wasn’t until 1995 that 3-D video cards became widely available for consumer PCs.<sup id="fnref:73"><a href="#fn:73" class="footnote" rel="footnote" role="doc-noteref">73</a></sup> In 3-D video games for PCs “[i]n 1995/1996, it was not uncommon to have 30-50% of the game screen filled with polygons without textures” (according to an <a href="https://retro.swarm.cz/s3-virge-325-vx-dx-gx-gx2-series-of-early-3d-accelerators-deep-dive/"><strong>article</strong></a> that compared <em>Havoc</em> [1995] with <em>Mortal Kombat 4</em> [1997]).</li>
<li>This specification is not centered on video games that offer “3-D vision” (see note under “Frame rate”), given how rare they were before 2000.</li>
<li>The following suggests alternative primitive drawing rates an application can use.
<ul>
<li>Nadeau (1996)<sup id="fnref:74"><a href="#fn:74" class="footnote" rel="footnote" role="doc-noteref">74</a></sup>, mentions: “[A] typical software implementation of the graphics pipeline for a Pentium PC can draw about 90,000 triangles per second. At a 60-Hz video refresh rate, the software can draw about 1500 triangles per refresh”. Assuming the Pentium processor’s speed is 100 megahertz this suggests a target rate of 15 triangles per megahertz per frame. For example, if the target processor speed is 250 megahertz or faster, the target rate is 3750 triangles per frame.</li>
<li>The first version of the Renderware library (1994) was claimed to draw about 40,000 polygons per second at resolution 400 × 400 on a 50-megahertz processor.<sup id="fnref:75"><a href="#fn:75" class="footnote" rel="footnote" role="doc-noteref">75</a></sup> Assuming an average of 60 frames per second, the target rate would be about 13.33 polygons per megahertz per frame, or 666 polygons per frame.
<a id="Graphics_in_video_arcade_games"></a></li>
</ul>
</li>
</ul>
<h4 id="graphics-in-video-arcade-games">Graphics in video arcade games</h4>
<ul>
<li>From 1971 to 1979, arcade games tended to have white visuals drawn on a black screen; the screen image was one bit per pixel. Some arcade cabinets in the late 1970s had a colored semitransparent overlay in front of the screen to lend color to the otherwise white graphics (an example is <em>Lunar Rescue</em> [1979]).</li>
<li>The practice of drawing graphics on a mostly black screen continued up to the early 1980s, but this time they were colored by the game itself rather than by an overlay.</li>
<li>The visuals of some arcade games from 1979 to the early 1980s were made of white line segments. Notable examples are <em>Asteroids</em> (1979) and <em>Battlezone</em> (1980). In <em>Space Fury</em> (1981) and <em>Star Wars</em> (1983), these line segments were even multicolored.</li>
<li>Graphics made of tiles and sprites were popularized by the arcade game <em>Galaxian</em> (1979).</li>
<li>Most arcade games before 1995 had a resolution from 46,080 pixels (192 × 240 or 240 × 192) through 98,304 pixels (256 × 384 or 384 × 256). The following were exceptions:
<ul>
<li>Certain games by Taito that combine two or three video screens into one (for example, <em>Darius</em> [1987] and <em>The Ninja Warriors</em> [1987]).</li>
<li>The Midway MCR family of arcade machines (1980 to about 1986) had a screen resolution of 480 × 480, 512 × 448, or 512 × 480, but backgrounds were drawn at half the resolution of sprites. Examples include <em>Tapper</em> (1982) and <em>Wacko</em> (1983).</li>
</ul>
</li>
<li>If an arcade game employed 2-D visuals with tiles and sprites, each tile and sprite tended to use no more than 16 colors, and semitransparency was not used.</li>
<li>There have been so-called cinematic arcade video games, such as <em>Wild Gunman</em> (1974), <em>Astron Belt</em> (1982), and <em>Dragon’s Lair</em> (1983).</li>
</ul>
<p><a id="Screen_image_effects_filters"></a></p>
<h4 id="screen-image-effects-filters">Screen image effects (filters)</h4>
<p>Outside the scope of this challenge are effects that—</p>
<ul>
<li>modify the game screen image to emulate how it would look on CRT displays and other analog displays<sup id="fnref:76"><a href="#fn:76" class="footnote" rel="footnote" role="doc-noteref">76</a></sup>,</li>
<li><a href="https://www.pcgamingwiki.com/wiki/Glossary:Scaling"><strong>scale</strong></a> the game screen to fit the height or width of the player’s display,<sup id="fnref:77"><a href="#fn:77" class="footnote" rel="footnote" role="doc-noteref">77</a></sup> or</li>
<li>simulate the interlaced video display of certain TV screens, especially NTSC- and PAL-compatible ones.</li>
</ul>
<p>This specification assumes those effects are not in place. A game is allowed to have those effects, but applying them by default is not within the spirit of this specification (with the exception of magnifying the game screen image using point filtering).</p>
<p><a id="Sounds"></a></p>
<h4 id="sounds">Sounds</h4>
<ul>
<li>Besides the limitation on music, this specification has no further limitations on sounds.</li>
<li>Early game consoles supported sound only through one or more <em>programmable sound generators</em>, such as square and triangle wave generators, as opposed to digitized sounds<sup id="fnref:78"><a href="#fn:78" class="footnote" rel="footnote" role="doc-noteref">78</a></sup>. Games that choose to constrain file size may wish to implement software versions of programmable sound generators for at least some of their sounds.</li>
<li>When digitized sounds are supported in classic games, they typically have a sample rate of 8000, 11,025, 22,050, or 44,100 hertz, are either mono or stereo, and take 8 or 16 bits per sample.<sup id="fnref:79"><a href="#fn:79" class="footnote" rel="footnote" role="doc-noteref">79</a></sup></li>
</ul>
<p><a id="Memory"></a></p>
<h4 id="memory">Memory</h4>
<ul>
<li>This specification does not impose a limit on graphical memory use (akin to the video memory, or VRAM, of a video card). Such a limit is optional. One suggested example, given in kibibytes, is the screen width times screen height divided by 24, which is slightly less than 13.2 million bytes for 640 × 480 resolution. (A kibibyte is 1024 bytes.) Imposing a limit on graphical memory use does not limit the size or number of textures, 3-D models, images, or other resource files a game can have.<sup id="fnref:80"><a href="#fn:80" class="footnote" rel="footnote" role="doc-noteref">80</a></sup></li>
<li>According to “<a href="https://www.dosdays.co.uk/topics/typical_pc_per_year.php"><strong>Typical PCs Each Year</strong></a>”, the following ranges of system memory were typical for PCs sold in the specified years:<sup id="fnref:81"><a href="#fn:81" class="footnote" rel="footnote" role="doc-noteref">81</a></sup>
<ul>
<li>1994: 4MB to 8 MB, with more expensive PCs having 16 MB.<sup id="fnref:82"><a href="#fn:82" class="footnote" rel="footnote" role="doc-noteref">82</a></sup></li>
<li>1997: 8MB to 32MB.<sup id="fnref:83"><a href="#fn:83" class="footnote" rel="footnote" role="doc-noteref">83</a></sup></li>
<li>1998: 32MB to 128MB.<sup id="fnref:84"><a href="#fn:84" class="footnote" rel="footnote" role="doc-noteref">84</a></sup></li>
</ul>
</li>
</ul>
<p><a id="Miscellaneous"></a></p>
<h4 id="miscellaneous">Miscellaneous</h4>
<ul>
<li>Support for high-dynamic-range or wide-color-gamut content is beyond the scope of this challenge.</li>
</ul>
<p><a id="Seeking_Comments"></a></p>
<h3 id="seeking-comments">Seeking Comments</h3>
<p>As with the rest of this open-source article, <a href="https://www.reddit.com/r/retrogamedev/comments/1rl36fo/pre2000_computer_graphics_for_modern_video_games/"><strong>comments on this specification</strong></a> are welcome. But most useful would be comments that improve or refine the specification to fit the graphical abilities of pre-2000 video games.</p>
<p>Examples are comments that give <em>measurements</em> (or references to other works that make such measurements) on the graphical performance actually achieved, in normal gameplay, by video games within the <a href="#Classic_Graphics_in_Scope"><strong>scope of the specification</strong></a>. (It bears repeating: <em>measurements</em>, not inferences or guesses from screenshots or videos.)</p>
<p>This includes statements like the following, with references or measurements:</p>
<ul>
<li>“Game X shows up to Y polygons per frame at screen resolution W [and Z frames per second]”.
<ul>
<li>Statements like this that relate to polygons or triangles per frame are hard to find and often anecdotal, and they cannot always be inferred from screenshots or videos of gameplay. For example:<br />(1) “A typical scene in a current [PC] application has 2000 to 2500 triangles per frame” (Fosner 1999)<sup id="fnref:85"><a href="#fn:85" class="footnote" rel="footnote" role="doc-noteref">85</a></sup>.<br />(2) According to the help for the 3DMark2000 benchmark, that benchmark comes with two game scenes that average up to 9,400 polygons in low detail and up to 55,000 in high detail.<br />(3) The game engine for <em>SpecOps: Rangers Lead the Way</em> (1998) targeted 10,000 triangles per frame <sup id="fnref:86"><a href="#fn:86" class="footnote" rel="footnote" role="doc-noteref">86</a></sup>. So did <em>Quake III Arena</em> (1999) (John Carmack .plan, Sep. 2, 1999).</li>
</ul>
</li>
<li>“Scenes in game X have Y triangles on average”.</li>
<li>“Game X shows no more than [16 or 256] simultaneous colors”.</li>
<li>“Game X uses Y bytes of memory while running on Windows 98”.<sup id="fnref:87"><a href="#fn:87" class="footnote" rel="footnote" role="doc-noteref">87</a></sup></li>
<li>“Game X shows up to Y sprites at a time [at screen resolution Z]” (for 2-D games such as those built using the tool Director, then by Macromedia).</li>
<li>The 2-D game X, from year Y, supports a <a href="https://peteroupc.github.io/graphicsapi.html#2_D_Graphics"><strong>given 2-D graphics capability</strong></a> (for example, 2-D rotations of sprites; filling ellipses with a solid color; flood filling; antialiasing of lines and shapes; translucent alpha blending; translucent sprites).</li>
<li>The 3-D game X, from year Y, supports a <a href="https://peteroupc.github.io/graphicsapi.html#3_D_Graphics"><strong>given 3-D graphics capability</strong></a> (for example, Gouraud shading; bump mapping; edge antialiasing; alpha blending; texture mapping of most polygons in a scene; or MIP mapping).</li>
</ul>
<p>(Those statements will also help me define constraints for video games up to an earlier year than 1999.)</p>
<p>Statements like the following are also useful, with references:</p>
<ul>
<li>“In year X [1999 or earlier], Y% of PC users used screen resolution Z”.</li>
<li>In year X, a given 3-D graphics capability became typical in 3-D video games.</li>
<li>In year X, a given 2-D graphics capability became typical in 2-D video games.</li>
<li>“In year X [1999 or earlier], Y% of home computers in use were equipped with Z million bytes of memory”.</li>
<li>“In year X, Y% of home PCs were equipped with 3-D video cards”.</li>
<li>A market-share-weighted average of system memory requirements of video games in year X.</li>
<li>On a market-share-weighted basis, X% of video games in year Y—
<ul>
<li>ran on [16 or 256]-color display modes, or</li>
<li>had real-time 3-D rendering, or</li>
<li>were played on arcade machines, or</li>
<li>were played on PCs, or</li>
<li>were played on game console Z.</li>
</ul>
</li>
</ul>
<p>By contrast, statements like the following are not very useful, since they often don’t relate to the actual performance of specific video games:</p>
<ul>
<li>“Game console/video card X can process up to Y <a href="https://developer.arm.com/community/arm-community-blogs/b/mobile-graphics-and-gaming-blog/posts/triangles-per-second-performance-metric-or-chocolate-teapot"><strong>triangles per second</strong></a>”.</li>
<li>“Game console/video card X can render up to Y polygons per frame”.</li>
<li>“Game console/video card X can render up to Y pixels per second”.</li>
<li>“Game X renders Y triangles per second”, without stating the frame rate or the screen resolution.</li>
<li>“Game X issues Y draw calls per frame”, since a single draw call can draw one triangle or tens of thousands.</li>
<li>“Character models in game X average Y triangles”.</li>
</ul>
<p>The following are examples of the kind of statements desired:</p>
<ul>
<li><em>Actua Soccer</em> (<em>VR Soccer ‘96</em>) (1995) <a href="http://www-graphics.stanford.edu/~bjohanso/asoccer_stats/"><strong>averaged 776 triangles per frame</strong></a> at 640 × 480 resolution.</li>
<li><em>Terminal Velocity</em> (1995) <a href="http://www-graphics.stanford.edu/~bjohanso/tv_stats/"><strong>averaged 498 triangles per frame</strong></a> at 640 × 480 resolution.</li>
<li>A benchmark of <em>Quake III Arena</em> averaged about 3,250 and topped out at about 6,970 triangles per frame after back-face culling, at screen resolution 640 × 480 (Antochi et al. 2003)<sup id="fnref:88"><a href="#fn:88" class="footnote" rel="footnote" role="doc-noteref">88</a></sup>, (Antochi et al. 2004)<sup id="fnref:89"><a href="#fn:89" class="footnote" rel="footnote" role="doc-noteref">89</a></sup>.</li>
<li>The game <em>Star Wars Racer</em> (1999) <a href="https://x.com/jonk1969/status/1636183310203498496"><strong>targeted a limit of 3000 polygons per frame</strong></a> as well as texture sizes that appeared to respect the Nintendo 64’s 4096-byte texture cache.</li>
</ul>
<p><a id="Further_Reading"></a></p>
<h3 id="further-reading">Further Reading</h3>
<ul>
<li>Abrash, M., <a href="https://github.com/jagregory/abrash-black-book"><strong><em>Michael Abrash’s Graphics Programming Black Book: Special Edition</em></strong></a>, 1997.</li>
<li>(Akenine-)Möller, T., Haines, E., <em>Real-Time Rendering</em> (first edition), 1999.</li>
<li>Amanatides, John, and Andrew Woo. “A fast voxel traversal algorithm for ray tracing.” Eurographics. Vol. 87. No. 3. 1987. <a href="http://www.cse.yorku.ca/~amana/research/grid.pdf"><strong>http://www.cse.yorku.ca/~amana/research/grid.pdf</strong></a></li>
<li>Apple Computer Inc., <em>3D Graphics Programming With QuickDraw 3D 1.5.4</em>, 1997.</li>
<li>Apple Computer Inc., “<a href="https://developer.apple.com/library/archive/technotes/tn/tn1125.html"><strong>Building a 3D application that calls RAVE</strong></a>”, Technical Note TN1125, May 4, 1998.</li>
<li>Anderson, G (ed.), <em>More Tricks of the Game Programming Gurus</em>, Sams, 1995. ISBN 0-672-30697-2.</li>
<li>CSA T500-1983/ANSI X3.110-1983/FIPS PUB 121, “Videotex/Teletext Presentation Level Protocol Syntax”, also known as the North American Presentation-Level-Protocol Syntax. For an overview of this syntax, see the series of articles titled “NAPLPS: A New Standard for Text and Graphics” in <em>BYTE</em>, February 1983, March 1983, April 1983, and May 1983.</li>
<li>Gery, R., “Bitmaps with Transparency”, Microsoft Developer Network, Jun. 1, 1992.</li>
<li>Houston, B., “Rendering Real-Time 3D Before GPUs”, Jul. 17, 2026. <a href="https://ben3d.ca/blog/rendering-real-time-3d-before-gpus"><strong>https://ben3d.ca/blog/rendering-real-time-3d-before-gpus</strong></a></li>
<li>International Telecommunication Union, <em>Conventional Television Systems</em>, ITU-R BT.470-6, 1998.</li>
<li>International Telecommunication Union, <em>International Interworking for Videotex Services</em>, ITU-T T.101, 1988.</li>
<li>Lamothe, A., et al., <em>Tricks of the Game Programming Gurus</em>, Sams, 1994. ISBN 0-672-30846-0.</li>
<li>Lamothe, A., <em>Black Art of 3D Game Programming</em>, Waite Group Press, 1995. ISBN 1-57169-004-2.</li>
<li>Lamothe, A., <em>Tricks of the 3D Game Programming Gurus: Advanced 3D Graphics and Rasterization</em>, Sams, 2003. Published after 1999, but most of the 3-D capabilities discussed there are within the spirit of this specification. ISBN 0-672-31835-0.</li>
<li>Lamothe, A., <em>Tricks of the Windows Game Programming Gurus</em>, Sams, 1999. ISBN 0-672-31361-8.</li>
<li>J. McCornack et al., <em>Tricks of the Mac Game Programming Gurus</em>, Hayden Books, 1995. ISBN 1-56830-183-9.</li>
<li>Microsoft Corp., “AVI Video Authoring Tips & Compression Options Dialog Box”, Microsoft Knowledge Base article Q139826, 1995.</li>
<li>PC hardware guidelines:
<ul>
<li>Multimedia PC Marketing Council, “Multimedia PC Level 1 and Level 2 Specifications” (May 1993), also in Microsoft Knowledge Base article Q106055 (1993). The two specifications are called MPC Level 1 (from 1990) and MPC Level 2 (from 1993) in this document.</li>
<li>In <em>Dr. Dobbs’ Journal</em>, Sep. 1995 (“Of Interest”), it was announced that the Multimedia PC Software Publishers Association released an MPC Level 3 specification.</li>
<li>Microsoft Corp., <em>Hardware Design Guide for Microsoft Windows 95</em>, Microsoft Press, 1994. ISBN 1-55615-642-1. This book is called the PC 95 Guide in this document.</li>
<li>Microsoft Corp., <em>Hardware Design Guide Supplement for Microsoft Windows 95</em>, 1996.</li>
<li>Microsoft Corp., <em>PC 97 Hardware Design Guide</em>, Microsoft Press, 1997. ISBN 1-57231-381-1.</li>
<li>Intel & Microsoft, <em>PC 98 System Design Guide</em>, Microsoft Press, 1997. ISBN 1-57231-716-7.</li>
<li>Intel & Microsoft, <em>PC 99 System Design Guide</em>, Microsoft Press, 1998. ISBN 0-7356-0518-1.</li>
<li>Intel & Microsoft, <em>PC 2001 System Design Guide</em>, 2000.</li>
</ul>
</li>
<li>Roca, Jordi, et al., “<a href="https://ieeexplore.ieee.org/abstract/document/4086130"><strong>Workload Characterization of 3D Games</strong></a>”, <em>2006 IEEE International Symposium on Workload Characterization</em>. IEEE, 2006. Study on measuring certain features of 3-D games that are of interest in this specification, including triangles per frame. See the <a href="https://github.com/attila-gpu/attila-sim"><strong><code>attila-sim</code> repository</strong></a>.</li>
<li>Rodent, H., “Animation in Win32”, Microsoft Developer Network, Feb. 1, 1994.</li>
<li>Saettler, Matt, “Graphics Design and Optimization”, Multimedia Technical Note (Microsoft), 1992.</li>
<li>TeleGrafix Communications, Inc, “RIPscrip Graphics Protocol Specification”, revision 1.54, July 19th, 1993.</li>
<li>Thompson, N., <em>3D Graphics Programming for Windows 95</em>, Microsoft Press, 1996. ISBN 1-57231-345-5.</li>
<li>Thompson, N., <em>Animation Techniques in Win32</em>, Microsoft Press, 1995. ISBN 1-55615-669-3.</li>
<li>Woo, Mason, et al., <em>OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 1.1</em>, second edition, Addison Wesley Longman, 1997. ISBN 0-201-46138-2.</li>
</ul>
<p><a id="Building_a_Public_Domain_music_synthesis_library_and_instrument_banks"></a></p>
<h2 id="building-a-public-domain-music-synthesis-library-and-instrument-banks">Building a Public-Domain music synthesis library and instrument banks</h2>
<p>To improve support for MIDI (Musical Instrument Digital Interface) music playback in open-source and other applications, I challenge the community to write the following items, all of which must be released to the public domain or under the Unlicense.</p>
<ul>
<li>A cross-platform open-source library for <em>software</em> synthesis (translation into digitized sound) of MIDI data stored in standard MIDI files (SMF, .mid), using instrument sound banks (synthesizer banks) in SoundFont 2 (.sf2), Downloadable Sounds (.dls), and in OPL2, OPL3, and other FM synthesis sound banks, and possibly also in Timidity++/UltraSound patch format (.cfg, .pat). (Similar to <em>Fluidsynth</em>, but in the public domain or under the Unlicense. Instrument sound banks are files that describe how to render MIDI instruments as sound. In addition, the source code in the nonpublic-domain <em>foo_midi</em>, <em>libADLMIDI</em>, <em>libOPNMIDI</em>, <em>OPL3BankEditor</em>, and <em>SpessaSynth</em> may be useful here, but review their licenses first.)
<ul>
<li>The library should support popular loop-point conventions found in MIDI files.</li>
<li>The library should support seeking of MIDI files such that a pause and resume function can be offered by a media player.</li>
</ul>
</li>
<li>An instrument sound bank for wave-table synthesis of all instruments and percussive (drum) noises in the General MIDI System level 1 specification.
<ul>
<li>Instruments should correspond as closely as possible to those in that specification, but should be small in file size or be algorithmically generated.</li>
<li>Instruments can be generated using the public-domain single-cycle wave forms found in the AdventureKid Wave Form collection, found at: <a href="https://github.com/KristofferKarlAxelEkstrand/AKWF-FREE"><strong>AKWF-FREE</strong></a>.</li>
<li>The samples for each instrument may, but need not, be generated by an algorithm, such as one that renders the instrument’s tone in the frequency domain. An example of this is found in <a href="https://github.com/apple/openjdk/blob/xcodejdk14-release/src/java.desktop/share/classes/com/sun/media/sound/EmergencySoundbank.java"><strong><code>com.sun.media.sound.EmergencySoundbank</code></strong></a>, which however is licensed under the GNU General Public License version 2 rather than public domain.</li>
<li>The instrument sound bank should be in either SoundFont 2 (.sf2) or Downloadable Sounds (.dls) format. See next section on a challenge to writing a guide on sound bank development.</li>
<li>The volume of all instruments in the sound bank should be normalized; some instruments should not sound louder than others.</li>
</ul>
</li>
<li>An instrument sound bank for FM synthesis of all instruments and percussive noises in the General MIDI System level 1 specification. Instruments should correspond as closely as possible to those in that specification.</li>
</ul>
<p><a id="Other_Challenges_and_Projects"></a></p>
<h2 id="other-challenges-and-projects">Other Challenges and Projects</h2>
<p>Other challenges and projects I make to the computer community.</p>
<p>None of the following creations should be generated by artificial-intelligence tools or with their help.</p>
<p><a id="Classic_desktop_wallpaper"></a></p>
<h3 id="classic-desktop-wallpaper">Classic desktop wallpaper</h3>
<p>See the “<a href="https://peteroupc.github.io/classic-wallpaper"><strong>peteroupc/classic-wallpaper</strong></a>” repository for a challenge on creating tileable desktop wallpapers with a limited selection of colors and limited dimensions in pixels — such wallpapers are getting ever harder to find because desktop backgrounds today tend to cover the full computer screen, to employ thousands of colors, and to have a high-definition resolution (1920 × 1080 or larger).</p>
<p><a id="Button_and_border_styles_for_classic_interfaces"></a></p>
<h3 id="button-and-border-styles-for-classic-interfaces">Button and border styles for classic interfaces</h3>
<p>See <a href="https://peteroupc.github.io/classic-wallpaper/docs/uielements.html#Button_and_Border_Drawing_Challenge"><strong>“Traditional User-Interface Graphics”</strong></a> for a challenge on writing computer code (released to the public domain or under the Unlicense) to draw button and border styles for classic graphical user interfaces.</p>
<p><a id="Sound_bank_development_guide"></a></p>
<h3 id="sound-bank-development-guide">Sound bank development guide</h3>
<p>Write an open-source and detailed guide on using free-of-cost software to produce decent-quality instrument banks from the recordings of real musical instruments (rather than copying or converting other instrument banks or recording from commercial synthesizers). See the section on <a href="#Building_a_Public_Domain_music_synthesis_library_and_instrument_banks"><strong>building instrument banks, earlier</strong></a>. For this purpose, a sound bank in SoundFont 2 or Downloadable Sounds format that is of decent quality is about 4 million bytes in size.</p>
<p><a id="Guide_for_creating_3_D_models_in_the_pre_2000_style"></a></p>
<h3 id="guide-for-creating-3-d-models-in-the-pre-2000-style">Guide for creating 3-D models in the pre-2000 style</h3>
<p>Develop a guide for creating 3-D models for use in modern video games that follow the <a href="#Graphics_Challenge_for_Classic_Style_Games"><strong>specification</strong></a> given earlier on classic (pre-2000) 3-D graphics, in a similar vein to “<a href="https://threedium.io/3d-model/game-ready"><strong>Game-Ready 3D Models: Requirements, Creation, and Export</strong></a>” <sup id="fnref:90"><a href="#fn:90" class="footnote" rel="footnote" role="doc-noteref">90</a></sup>. Notably, no shader-based techniques should be required for any such models, and advice should apply to models for a game just as though the game were developed in 1999 (or an earlier year) rather than today, but the use of modern creation tools is allowed. (For example, instead of normal, roughness, or ambient-occlusion maps, late-1990s 3-D game models typically employed light maps and bump maps, and such models were generally much coarser than today’s models.)</p>
<p><a id="Book_form_tutorial_on_pre_2000_computer_graphics_programming"></a></p>
<h3 id="book-form-tutorial-on-pre-2000-computer-graphics-programming">Book-form tutorial on pre-2000 computer graphics programming</h3>
<p>Write a free and open-source tutorial on game graphics programming using the pre-2000 graphic style emphasized in the <a href="https://peteroupc.github.io/graphics.html#Graphics_Challenge_for_Classic_Style_Games"><strong>specification</strong></a> given earlier, with the following features:</p>
<ol>
<li>The tutorial is book-length, printable, and programming-language neutral.</li>
<li>The tutorial should cover all 2-D and 3-D concepts needed to exploit the specification fully, such as the concepts of tiles, sprites, 2-D layers, textures, 3-D triangles, and features for 3-D graphics.</li>
<li>The tutorial explains math concepts to readers as necessary, without assuming prior knowledge of math higher than basic algebra.</li>
<li>The tutorial should include checks for understanding, guided practice, and independent practice exercises. The tutorial may also include review (retrieval practice) of past concepts.</li>
<li>The tutorial does not require the use of hardware acceleration, OpenGL, or Direct3D in the practice exercises. (See definition of “rendered in software” in the specification.)</li>
</ol>
<p>The following are recommended:</p>
<ul>
<li>Graphics programming with a limited-color frame buffer (such as 16 colors or 256 colors) should be included.</li>
<li>The guided and independent practice should lead to readers writing a feature-rich software renderer that implements the pre-2000 graphics specification without third-party software libraries.</li>
</ul>
<p>Similar tutorials are <a href="https://gabrielgambetta.com/computer-graphics-from-scratch/"><strong><em>Computer Graphics from Scratch</em></strong></a> by Gabriel Gambetta and the <a href="https://haqr.eu/tinyrenderer/"><strong>tiny-renderer tutorial</strong></a> by Dmitry Sokolov, although they are not always geared toward the visuals in pre-2000 video games. For example, Gambetta covers ray tracing (which is outside this specification’s scope) but not sprites or other 2-D concepts.</p>
<blockquote>
<p><strong>Example:</strong> A potential list of topics the tutorial can have:</p>
<ul>
<li>The game screen; Line drawing; Polygon and triangle filling; Circles and ellipses; Flood filling; Text rendering using line drawing; Shape drawing review;</li>
<li>Colors and color palettes; Image copying; Image stretching; Sprites; Tile maps and layers; Sprite animation; Text rendering using sprites and tiles; Image and sprite review;</li>
<li>Palette animation; Pixel formats; 2-D affine transformations; 2-D review;</li>
<li>3-D lines and triangles; 3-D transformations (including perspective correction); The “camera”;</li>
<li>Per-column ray casting; Hidden surface removal; Triangle clipping; Z buffering;</li>
<li>Shading (flat and Gouraud) and texture mapping; Texture blending; Specular highlighting;</li>
<li>Fixed-point numbers; MIP mapping; Fog; Combining 2-D and 3-D; 3-D review.</li>
</ul>
<p>Examples of exercises for line drawing are an exercise for drawing polygons, and another for plotting Bézier curves.</p>
</blockquote>
<p><a id="Acknowledgments"></a></p>
<h2 id="acknowledgments">Acknowledgments</h2>
<p>I acknowledge the advice of the <code>gameenginedevs</code> and <code>programming</code> communities on Reddit.</p>
<p><a id="License"></a></p>
<h2 id="license">License</h2>
<p>Any copyright to this page is released to the Public Domain. In case this is not possible, this page is also licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/"><strong>Creative Commons Zero</strong></a>.</p>
<p><a id="Notes"></a></p>
<h2 id="notes">Notes</h2>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:1">
<p>The following are examples of a graphics library that follows the spirit, even if not the letter, of this specification: <a href="https://github.com/megamarc/Tilengine"><strong><em>Tilengine</em></strong></a>, <a href="https://github.com/rxi/kit/"><strong><em>kit</em></strong></a>, <a href="https://github.com/mattiasgustavsson/dos-like"><strong><em>DOS-like</em></strong></a>, <a href="https://github.com/raysan5/raylib"><strong><em>raylib</em>’s <code>rlsw</code> software renderer</strong></a>, <a href="https://github.com/morgan3d/quadplay"><strong><em>quadplay✜</em></strong></a>, <a href="https://github.com/nesbox/TIC-80"><strong><em>TIC-80</em></strong></a>. Michal Strehovský published an <a href="https://migeel.sk/blog/2024/01/02/building-a-self-contained-game-in-csharp-under-2-kilobytes/"><strong>interesting technique to create small game applications</strong></a>, and so did <a href="https://www.codeslow.com/2019/12/tiny-windows-executable-in-rust.html"><strong>Jani Peltonen</strong></a>.<br />I offer a <a href="https://gist.github.com/peteroupc/f1a5d8e45e27123b86b284271cfd802b"><strong>template for Win32 applications</strong></a> that supports 8- and 24-bit-per-pixel game images and paints finished game images using <code>StretchDIBits</code>.<br />By contrast, even though today’s Unity and Unreal game engines can allow the making of games with “classic graphics”, they are far from lightweight and their use is not within the spirit of this challenge. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:2">
<p>A computer has adequate performance for pre-2000 graphics if it achieves a score of—<br />(a) 3108 or more 3D marks on the 3DMark2000 benchmark (640 × 480) when run without hardware acceleration, or<br />(b) 195 or greater on the 3DMark2000 CPU speed test.<br />Both figures correspond to the running of two visually demanding 3-D demos, at three levels of detail each, at 60 frames per second (adjusted downward as needed if a demo’s detail level averages more than 12,800 triangles per frame; see the section “Test Descriptions” in the 3DMark2000 help). <a href="#fnref:2" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:3">
<p>One editor specialized for creating classic 3-D models is the open-source tool <a href="https://www.blockbench.net/"><strong><em>Blockbench</em></strong></a>. For classic 3-D scenes, there is the open-source tool <a href="https://trenchbroom.github.io/"><strong><em>Trenchbroom</em></strong></a>. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:4">
<p>There are many <a href="https://developer.arm.com/community/arm-community-blogs/b/mobile-graphics-and-gaming-blog/posts/triangles-per-second-performance-metric-or-chocolate-teapot"><strong>definitions of triangles</strong></a> per frame. One definition is the triangles processed each frame after their vertices are transformed but before they are clipped (corresponding to the <code>GL_PRIMITIVES_GENERATED</code> query in <a href="https://registry.khronos.org/OpenGL/specs/gl/glspec31.pdf"><strong>OpenGL 3.1</strong></a>, section 2.16). Another definition (often called <em>visible triangles</em>) is the number of triangles under the first definition that are neither back-facing nor totally outside the view volume. Clipping these visible triangles to the view volume (which can sometimes produce more triangles) leads to a third definition: the triangles inside the volume that result after this clipping. A similar situation occurs with “primitives per frame” rather than “triangles per frame”. For purposes of this specification, an overestimate of primitives per frame (such as in the first definition) is better than an underestimate. The maximum number of primitives per frame in this specification was determined based on a target rate of 60 frames per second. <a href="#fnref:4" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:4:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:5">
<p>For example, see “Optimizing OpenGL drivers for Quake3” by John Carmack, referenced in .plan, April 30, 1999. But primitives with two or more textures are a feature hardly seen before the late 1990s. See that document as well as Abrash (1997), chapters 69-70. <a href="#fnref:5" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:6">
<p><em>Quake</em> (1996) also employed <em>subdivision rasterization</em> for drawing small and relatively distant triangles whose vertices are rounded to integers, an algorithm likewise in scope here (Abrash (1997), chapter 69). <a href="#fnref:6" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:7">
<p>Antialiasing “<a href="https://imagequalitymatters.blogspot.com/2011/01/retro-tech-analysis-virtua-racing-md-vs.html"><strong>didn’t appear in home console graphics architectures</strong></a> until the debut of the [Nintendo 64] in late 1996”. McCornack et al. (1995) considers antialiasing among the features “unlikely” to be needed in game programming. <a href="#fnref:7" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:8">
<p>Perspective correction accounts for distance from the viewer: closer objects appear larger. The lack of perspective correction (as in what is called <em>affine texture mapping</em>) contributed to the characteristic distortion and instability of 3-D graphics in many video games for the original PlayStation; so did the fact that triangles were drawn without smooth edges and with vertices placed at integer coordinates on the game screen. <a href="#fnref:8" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:9">
<p><em>Alpha blending</em>, also known as <a href="https://ciechanow.ski/alpha-compositing/"><strong><em>alpha compositing</em></strong></a>, is the mixing of a color with an image’s existing color, with possible translucency (semitransparency). But alpha blending to an image that can store translucent pixels (so-called “destination alpha blending”) was recommended, not required, in the <em>PC 97 Hardware Design Guide</em>, the <em>PC 98 System Design Guide</em>, and the <em>PC 99 System Design Guide</em>. Moreover, alpha blending was “relatively new to PC games” at the time of <em>Quake</em>’s launch in 1996, according to Abrash (1997), and is practically not discussed at all in McCornack et al. (1995). Only images with opaque and/or transparent pixels tended to be supported in early-1990s video games. <a href="#fnref:9" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:10">
<p>It is being considered whether to replace these 2-D limits with one of the following alternatives:<br /><br />1. Instead of tiles, sprites, and layers, the game uses a <em>frame buffer</em> (array of color samples, called pixels, in computer memory) with no more than 8 bits per pixel (no more than 256 simultaneous colors) and all visuals in the game must be rendered in software (see the specification’s definition of “rendered in software”). Further efforts to define 2-D game programming are in <a href="https://peteroupc.github.io/graphicsapi.html"><strong>a page on a lean graphics API</strong></a>.<br />2. The 2-D limits in the specification apply, but instead of replacing a 2-D layer, the 3-D layer is simply a special sprite that covers the game screen (the usual size limits for sprites don’t apply) and can have transparent and translucent pixels.<br />3. Same as (2), but in addition, there are no tiles or 2-D layers (all the graphics are sprites).<br /><br />The tile-based limits in this specification also suit games that support only text display, and thus have visuals that resemble the text modes (as opposed to graphics modes) found in PCs and computer terminals. <a href="#fnref:10" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:11">
<p>The Neo Geo (1990) has only one 2-D layer; the rest of the visuals are sprites drawn below that layer. <a href="#fnref:11" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:12">
<p>This drawing can be done in many ways: for example, by designating pixels with a given label, say, 0, as transparent (in a process also known as <em>chroma keying</em>), or designating pixels that are the same as the upper-left pixel as transparent [Rodent 1994], or preparing a two-color mask identifying the pixels to be drawn [Gery 1992]. <a href="#fnref:12" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:13">
<p>Standard MIDI files should be played back using a cross-platform open-source software synthesizer (see section “Building a Public-Domain music synthesis library and instrument banks”), using either FM or wave-table synthesis; most modern PCs no longer come with hardware synthesizers. I note that it’s possible to write an FM software synthesizer supporting every MIDI instrument in less than a million bytes of code.<br />Standard MIDI files organize MIDI commands into up to 16 <em>channels</em>, each occupied by at most one “instrument” at a time. Under MPC Level 1, the first ten channels were intended for high-end synthesizers (where the tenth is percussion); the thirteenth through sixteenth, for low-end ones (sixteenth is percussion), and the nonpercussion channels were arranged in decreasing order of importance. This convention was abandoned with the rise in support for the General MIDI System level 1 (see Microsoft Knowledge Base article Q141087, “DOCERR: MarkMIDI Utility Not Provided in Win32 SDK”, 1995): now all 16 channels are supported (with only the tenth for percussion) and need not be arranged by importance. <a href="#fnref:13" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:13:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:14">
<p>If the game screen image uses two colors only (such as black and white), the game could choose to allow it to have up to 800,000 total pixels. For example, a 1024 × 768 display has 786,432 total pixels. However, two-color graphical display modes larger than 307,200 total pixels are probably rare among consumers. The modern game <em>Return of the Obra Dinn</em> employs a two-color 800 × 450 display (378,000 total pixels) (but even so this resolution was <a href="https://forums.tigsource.com/index.php?topic=40832.msg1363742#msg1363742">“up from 640[ × ]360”</a>).<br /><br />In the Godot engine, the screen resolution corresponds to the “Viewport Width” (<code>window/size/viewport_width</code>) and “Viewport Height” (<code>window/size/viewport_height</code>) project settings, along with <code>window/stretch/mode=viewport</code> and <code>window/stretch/scale_mode=integer</code>. For the Unity engine, there is advice from 2019 relating to the visual style in <a href="https://blog.unity.com/technology/2d-pixel-perfect-how-to-set-up-your-unity-project-for-retro-8-bits-games"><strong>“8-bit”</strong></a> and <a href="https://blog.unity.com/technology/2d-pixel-perfect-how-to-set-up-your-unity-project-for-retro-16-bit-games"><strong>“16-bit”</strong></a> game consoles. In Unreal Engine, the screen resolution apparently corresponds to <code>ResolutionSizeX</code> and <code>ResolutionSizeY</code>. But a lighter-weight graphics engine than Unity, Unreal, or even Godot would better suit the spirit of this specification. <a href="#fnref:14" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:15">
<p>The suggested width and height for tiles is 8 pixels by 8 pixels. <a href="#fnref:15" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:16">
<p>Tile- and sprite-based graphics were in place largely because they saved memory. Indeed, this system, present in the Nintendo DS and many earlier game consoles, was abandoned in the Nintendo 3DS in favor of a frame buffer (see the “Architecture of Consoles” series by Rodrigo Copetti).<br />Game consoles employing tile-based visuals tended to limit not only the number of sprites per frame, but also the number of sprites per row of pixels, but a per-row limit is not adopted here. As for the per-frame limit, the Famicom/Nintendo Entertainment System (1983), SEGA Master System/SEGA Mark III (1985), and PC Engine/TurboGrafx 16 (1987) had a limit of 64 sprites; the Game Boy (1989), 40; the SEGA Mega Drive/Genesis (1988), 80; the Super Famicom/Super Nintendo Entertainment System (1990), 128; and the relatively expensive Neo Geo (1990), 381. Again, see the “Architecture of Consoles” series by Rodrigo Copetti. <a href="#fnref:16" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:17">
<p>SEGA arcade machines from the 1980s could scale (stretch or shrink) sprites horizontally and vertically in hardware (for example, <em>Turbo</em> [1981], <em>Hang-On</em> [1985], <em>Out Run</em> [1986]). In the Super Famicom/Super Nintendo Entertainment System (1990), sprites could not be scaled, but they could be flipped. <a href="#fnref:17" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:18">
<p>Saettler (1992) contains a rich discussion of graphics used in computer games and other audiovisual computer applications up to 1992. Not mentioned in that document are graphics resembling:<br /> (1) Segmented liquid-crystal displays, of the kind found in Nintendo’s Game & Watch and many Tiger Electronics handheld games. These are simple to emulate, though: design a screen-size image that assigns each segment a unique color and, each frame, draw black where the segments that are “on” are, and draw white (or another background) elsewhere on the screen.<br />(2) Vacuum fluorescent displays, notable in user interfaces of some media player applications that resemble a “stereo rack system”. <a href="#fnref:18" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:19">
<p>Home computers include IBM PC compatibles, PC-88 and PC-98 families, ZX-Spectrum, Atari ST family, MSX family, Commodore 64, Amiga family, Commodore PET and VIC-20, BBC Micro, Amstrad CPC, Acorn Archimedes, Tandy TRS-80, Sharp X1 and X68000, FM Towns, Apple II, and computers running MS-DOS, Windows (up to Windows 98), Macintosh operating system (Mac OS) up to 9.x, NeXTSTEP, OS/2, or X Window System. This category includes computers described as “Consumer PCs”, “Mobile PCs”, and “Entertainment PCs” in the <em>PC 99 System Design Guide</em>, chapter 1. <a href="#fnref:19" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:20">
<p>The first arcade video game, <em>Computer Space</em>, launched in 1971. <a href="#fnref:20" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:21">
<p>Videotex is an information exchange system involving video screens. Some videotex protocols supported exchanging images and line drawings in addition to text, and it’s these that are of particular interest. See the videotex references in “Further Reading”. However, distribution of video games over videotex seems to be rare; an early example is <em>Dire Straits</em> (1982). <a href="#fnref:21" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:22">
<p>The following video games before 2000 are suspected, but not yet confirmed, to show more than 20,000 triangles per frame, a performance level beyond the spirit of this challenge: <em>The Lost World: Jurassic Park</em> (1997), <em>Emergency Call Ambulance</em>, and <em>L.A. Machine Guns</em> for SEGA Model 3, and <em>Soul Calibur</em> and <em>Dead or Alive 2</em> for Dreamcast. See “<a href="#Seeking_Comments"><strong>Seeking Comments</strong></a>”. (<em>Test Drive Le Mans</em>, likewise claimed to have a high polygon count, came out in 2000 and is thus outside this specification’s scope.) <a href="#fnref:22" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:22:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:23">
<p>Versions 1.3 and later of OpenGL came after 2000. <a href="#fnref:23" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:24">
<p>OpenGL ES Shading Language and OpenGL ES 2.0, which came out in May 2009 and November 2010, respectively, enabled programmable “shaders”, which are beyond this specification’s scope. <a href="#fnref:24" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:25">
<p>An example is <em>Loom</em> (1990). <a href="#fnref:25" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:26">
<p>This was recommended for Macintosh games in McCornack et al. (1995), notably because 8-bit-per-pixel images transfer faster and save memory over images with more bits per pixel; see also chapter 70 of Abrash (1997) (dealing with the porting of an 8-bit-per-pixel game to a 16-bit-per-pixel video card). <a href="https://mavorsrants.blogspot.com/2012/04/total-annihilation-graphics-engine.html"><strong><em>Total Annihilation</em></strong></a> (1997) is an example of a game that limits itself to 256 colors. <a href="#fnref:26" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:27">
<p>The FAT file system follows complex rules; that is why these constraints call for a single ZIP file or Win32 program file. However, for games with multiple files, the following guidelines are helpful to simplify matters: (1) There are no more than 110 or 56 files (for high density or normal/double density, respectively), and there are no empty files. (2) When calculating total file size, round the size of files up to the nearest multiple of 512 bytes. (3) Each file’s name should consist of one to eight name characters, followed by a period (“.”), followed by one to three name characters. The name characters are basic uppercase letters (A to Z), basic digits (0 to 9), the hyphen (“-“), and the underscore (“_”). (4) Although the FAT file system supports subdirectories, there should be none under these guidelines. <a href="#fnref:27" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:27:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:27:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a> <a href="#fnref:27:3" class="reversefootnote" role="doc-backlink">↩<sup>4</sup></a></p>
</li>
<li id="fn:28">
<p>Popular file size limit of so-called “64K intros”. <a href="#fnref:28" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:29">
<p>A CD-ROM’s format differs from the FAT file system. In this case, the same guidelines as for FAT can be used, except: (1) There can be subdirectories, whose names follow the same rules as for files. (2) There can be more than 110 files. (3) When calculating total file size, round the size of files up to the nearest multiple of 32,768 bytes, and treat subdirectory entries as having 32,768 bytes. (4) Subdirectories should not be nested more than seven levels deep. <a href="#fnref:29" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:30">
<p>MS-DOS applications are normally limited to 640 kibibytes or less of <em>conventional memory</em>, along with whatever memory is carried by the video card. (PCs running on the very early Intel 8086 and 8088 processors can map out no more than 640 kibibytes of system memory.) 262,144 bytes is the usual minimum of graphics memory for VGA video cards. <a href="#fnref:30" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:31">
<p>It wasn’t until the Pentium processor’s advent that floating-point arithmetic was embraced in 3-D game programming: for example, see chapter 63 of Abrash (1997). <a href="#fnref:31" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:32">
<p>The use of 64-bit floating-point numbers (IEEE 754 binary64, or the commonly implemented meaning of the C language’s <code>double</code> type) is perhaps unusual in graphics programming before 2000. <a href="#fnref:32" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:33">
<p>This is the performance level targeted for the “<a href="https://expfunction.itch.io/cybervga"><strong>CyberVGA</strong></a>” engine by Burak Yazar. <a href="#fnref:33" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:34">
<p>Moreover, PC games before 2000 that required screen resolutions larger than 640 × 480 are rare, and according to PCGamingWiki they include the following games (most of which are 2-D): <em>Timon & Pumbaa’s Jungle Games</em> (1995); <em>Tequila & Boom Boom</em> (1995); <em>Romance of the Three Kingdoms IV: Wall of Fire</em> (1995/1996); <em>Links LS: 1998 Edition</em> (1997); <em>Emergency: Fighters for Life</em> (1998); <em>Championship Manager: Season 99/00</em> (1999); <em>Heroes of Might and Magic III</em> (1999); <em>Alien Nations</em> (1999); <em>Pizza Syndicate</em>/<em>Fast Food Tycoon</em> (1999); <em>Age of Empires II: The Age of Kings</em> (1999). <a href="#fnref:34" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:35">
<p>In addition to the resolutions shown here, there are modern games that employ low resolutions with the same 16:9 aspect ratio as high-definition displays. These include 640 × 360 (<em>Blasphemous</em> [2019]); 400 × 225 (<em>Unsighted</em>); 480 × 270 (<em>Enter the Gungeon</em>); 320 × 180 (<em>Celeste</em>).<br />Information about game consoles’ screen resolution can be found in Rodrigo Copetti’s “Architecture of Consoles” series. <a href="#fnref:35" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:36">
<p>VGA mode 12h (16 colors); VGA mode 11h (2 colors). <a href="#fnref:36" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:36:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:37">
<p>Nintendo 3DS lower screen; larger VGA “mode X” (256 colors); most common Nintendo 64 resolution; SEGA Mega Drive PAL. <a href="#fnref:37" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:37:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:38">
<p>Commodore 64; NEC PC-8001; VGA mode 13h (256 colors), especially seen in MS-DOS games; Color/Graphics Monitor Adapter (CGA) 4-color mode; Atari ST 16-color mode; <a href="https://blog.johnnovak.net/2022/04/15/achieving-period-correct-graphics-in-personal-computer-emulators-part-1-the-amiga"><strong>Amiga NTSC</strong></a>. <a href="#fnref:38" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:38:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:39">
<p>One commonly supported “super-VGA” mode, especially in mid-1990s gaming, and which was also recommended by the <em>PC 98 System Design Guide</em> (chapter 14, item 20). <a href="#fnref:39" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:40">
<p>One low resolution recommended by the <em>PC 98 System Design Guide</em> (chapter 14, item 20). <a href="#fnref:40" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:41">