Новости ChatGPT

Эволюция ПО в разработке игр на практике: 1981 — IBM PC, Софт и игра

Конфигурация

Несмотря на то, что IBM PC можно было приобрести в одном из двух вариантов, более дешевый не имеет смысла из-за серьезных ограничений по носителям(только кассеты) и возможностям BASIC (только текстовый режим без возможности работы с цветом). Для работы же с версией BASIC на дискете требовалась конфигурация на 48КБ из которых 32КБ забирала система при загрузке PC DOS с дискеты. Также ревизия 1981 года была ограничена 64кб памяти, а вариант на 256кб появился только в следующем году. Это, к слову, в некоторой мере объясняет большую редкость софта под IBM PC на кассетах будь то любительский или коммерческий (строго говоря, он редок и для TRS-80 c Apple II, но хотя бы для последнего известно некоторое количество игр в таком формате). Потому практически все ранние игры для IBM PC рассчитаны под конфиг с 48КБ базовой памяти. Дополнительные 16КБ кажутся относительно дешевыми при таких условиях, мышей еще не было (первая для IBM PC будет только в 1983 году), а джойстик можно будет приобрести потом (к этому времени оные формата Atari VCS/2600 - стик с одной кнопкой - стали стандартом и был доступен вариант известных под термином пэдл (paddle) для подобий Pong и Breakout).

Документация

За годы с момента выхода IBM PC полный комплект документации за 1981 год до сих не оцифрован. Из нее наиболее интересным является руководство по BASIC, включающее в том числе раздел с описанием команд.

Однако, оцифровано руководство в ревизии за май 1982 года (BASIC_1.1_May82), которое допустимо использовать, так как правки не значительны и со связанными с ними ситуациями вряд ли придётся столкнуться в ходе использования. Источником примеров программ и игр могут быть книги-сборники 101 BASIC Computer Games (первое издание - 07.1973, издание за март 1975 года) и BASIC Computer Games с More BASIC Computer Games (1978 и 1979 годы соответственно).

Софт

В сущности, в комплекте PC DOS из коробки был доступен только BASIC, а VisiCalc нужно было приобретать отдельно. Рассматривать последний смысла нет, так как оный к моменту выпуска IBM PC был доступен и на TRS-80 и смысла приобретать ту же программу для другой системы смысла не имело. Также самая ранняя версия VisiCalc для IBM PC доступна на Winworld, но не эмулируется ни в одном эмуляторе из-за специфической защиты от копирования , которая работает на секторно-байтовом уровне и ни одна реализация чтения образов дискет не учитывает такие особенности (в отличие от самих форматов, из которых можно произвести физическую запись на дискету, работоспособную на реальном железе). Чуть более поздняя версия заработала в Dosbox-X, а в PCBox происходит зависание (возможно, нужно больше 64КБ). Таким образом, последующая информация будет про BASIC.

Особенности и использование BASIC

Некоторые нюансы работы:

  • Произвольно редактировать нельзя: только последовательная построчная запись (компенсация — группировать строки особым образом и оставлять место для новых, так как BASIC умеет их подставлять последовательно: если добавить LINE 881 <Код>, то она встанет между 880 и 882 без участия пользователя).

  • Сохранение на кассету происходит только один раз, перезапись изменения не учитывает (компенсация — сделать новый образ кассеты и делать новое сохранение на неё).

  • Подставить уже готовый к загрузке.BAS файл (блокнот→ dosbox‑x → PCBox) нельзя: либо портятся или неверно интерпретируются строки в файле или обрабатывается только часть строк. Потому вводить только самостоятельно в эмуляторе (с другой стороны плюс — вникаешь в ход работы строк по ходу перепечатывания).

  • Использовать EDLIN для редактирования.BAS файла нельзя: он неправильно читает данные.

  • Нельзя произвольно редактировать строку: если в строке есть ошибка, то заменять нужно всю строку от её места (хинт — для замены одного символа на другой достаточно дойти до оного и сразу нажать на одну из нужных клавиш клавиатуры — старый символ заменится на новый).

  • Нельзя после загрузки.BAS файла с дискеты пересохранить на другую, только на ту же (компенсация — заранее сделать новую чистую дискету и отформатировать её; скопировать файл образа чистой дискеты переименовав её).

  • Нельзя залупить музыку (команды SOUND, PLAY).

  • Реализовать 160×100×16 возможно только через ассемблер (BASIC 1.x не поддерживает DATA).

  • Сохранение лучше делать в формате 'SAVE«TEST.BAS»,A'. без A будет сохранение в бинарном формате.

Приятный бонус - можно использовать BASIC в качестве простейшего псевдо-текстовика.

Нюансом в написании кода является использование нейросетей с последующей правкой в случае необходимости.

Программы

CP437 Draw (CP437DRW)

Простая рисовалка в текстовом режиме 80х25 с поддержкой цвета. Запросы (Qwen3-Max) - 1, 2.

10 REM CP437 Draw Tool 
20 SCREEN 0,1:WIDTH 80:KEY OFF:CLS 
30 COLOR 15,0 
40 CX=2:CY=2:CC=15:CH=32 
50 GOSUB 500 
60 REM Main Loop 
70 LOCATE CY,CX 
80 A$=INKEY$:IF A$="" THEN 80 
90 IF A$=CHR$(27) THEN CLS:COLOR 7,0:END 
100 REM Char navi 
110 IF A$="C" OR A$="c" THEN CH=(CH+1) MOD 255 
120 IF CH=12 THEN CH=13:REM Skip char 
130 IF A$="+" THEN CH=(CH+16) MOD 255 
140 IF A$="=" THEN CH=127 
150 IF A$="-" THEN CH=0 
160 REM Color change 
170 IF A$="Z" OR A$="z" THEN CC=(CC+1) MOD 16 
180 REM Char place 
190 IF A$=" " AND CH<>12 THEN COLOR CC,0:LOCATE CY,CX:PRINT CHR$(CH); 
200 REM Arrow keys 
210 IF A$=CHR$(0)+"H" THEN CY=CY-1:IF CY<2 THEN CY=2 
220 IF A$=CHR$(0)+"P" THEN CY=CY+1:IF CY>24 THEN CY=24 
230 IF A$=CHR$(0)+"K" THEN CX=CX-1:IF CX<2 THEN CX=2 
240 IF A$=CHR$(0)+"M" THEN CX=CX+1:IF CX>78 THEN CX=78 
250 REM Save/Load 
260 IF A$="P" OR A$="p" THEN GOSUB 700 
270 IF A$="S" OR A$="s" THEN GOSUB 700 
280 IF A$="R" OR A$="r" THEN GOSUB 800 
290 GOTO 70 
500 REM Draw border 
510 COLOR 7,0 
520 LOCATE 1,1:PRINT CHR$(201); 
530 LOCATE 1,79:PRINT CHR$(187); 
540 LOCATE 25,1:PRINT CHR$(200); 
550 LOCATE 25,79:PRINT CHR$(188); 
560 FOR Y=2 TO 24 
570 LOCATE Y,1:PRINT CHR$(186); 
580 LOCATE Y,79:PRINT CHR$(186); 
590 NEXT Y 
600 FOR X=2 TO 78 
610 LOCATE 1,X:PRINT CHR$(205); 
620 LOCATE 25,X:PRINT CHR$(205); 
630 NEXT X 
640 RETURN 
700 REM Save 
710 DEF SEG=&HB800 
720 BSAVE "IMG.SAV",0,&HFA0 
730 DEF SEG 
740 OPEN "IMG.VAR" FOR OUTPUT AS #1 
750 PRINT #1,CX,CY,CC,CH 
760 CLOSE #1 
770 PRINT"SAVED!" 
780 RETURN 
800 REM Load 
810 ON ERROR GOTO 900 
820 DEF SEG=&HB800 
830 BLOAD "IMG.SAV",0 
840 DEF SEG 
850 OPEN "IMG.VAR" FOR INPUT AS #1 
860 INPUT #1,CX,CY,CC,CH 
870 CLOSE #1 
880 GOSUB 500 
890 RETURN 
900 PRINT"No save found!":FOR T=1 TO 1000:NEXT T:RESUME NEXT
Объяснить код с

Примеры рисунков:

Music Maker (MUSMAKE)

Простая программа для набора нот для PLAY и SOUND. Запрос.

10 REM PLAY/SOUND Command Explorer 
20 DEFINT F,D 
30 ON ERROR GOTO 400 
40 CLS 50 PRINT"IBM PC BASIC PLAY/SOUND TESTER" 
60 PRINT"------------------------------" 
70 PRINT"Avaliable PLAY commands:" 
80 PRINT" A-G[#|+|-] : Notes (e.g., C+, D#)" 
90 PRINT" O<n> : Octave (0-6, default=4)" 
100 PRINT" N<n> : Note number (0-84, 0=rest)" 
110 PRINT" L<n> : Length (1-64, e.g., L4=quarter note)" 
120 PRINT" P<n> : Pause (rest) of length n" 
130 PRINT" T<n> : Tempo (32-255 BPM, default=120)" 
140 PRINT" . : Dotted note (e.g., C.)" 
150 PRINT" MF/MB : Music Foreground/Background" 
160 PRINT" MN/ML/MS : Normal/Legato/Staccato" 
170 PRINT" X<var> : Execute string variable (e.g., XMYTUNE$)" 
180 PRINT 
190 PRINT"SOUND: freq (37-32767), duration (0-65535 ticks; 18.2/sec)" 
200 PRINT 
210 GOSUB 300 
220 PRINT 
230 PRINT"Press M=PLAY, S=SOUND, E=EDIT, ESC=QUIT" 
240 K$=INKEY$:IF K$="" THEN 240 
250 IF K$="M" OR K$="m" THEN PLAY PLAYSTR$ 
260 IF K$="S" OR K$="s" THEN SOUND FREQ%,DUR% 
270 IF K$="E" OR K$="e" THEN GOSUB 300 
280 IF ASC(K$)=27 THEN SYSTEM 
290 GOTO 240 
300 REM Input 
310 INPUT"Enter PLAY string";PLAYSTR$ 
320 INPUT"Enter SOUND freq,dur (e.g., 440,18)";FREQ%,DUR% 
330 RETURN 
400 REM Error Handler 
410 PRINT"ERROR";ERR;"LINE";ERL 
420 PRINT"Press any key to continue..." 
430 WHILE INKEY$="":WEND 
440 RESUME 40 
Объяснить код с

Игра

В качестве теста попробовал сделать простенькую реализацию Space Invaders. Для этого документ по BASIC 1.10 перевел через Abbyy FineReader в текстовый формат (размер - 445КБ), а также сохранил вариант в RTF. После этого полученный текстовый файл с примерами на .BAS (Donkey.BAS, Sample.BAS) был загружен в Google Gemini 3 (Pro-версия, доступна минимум 1 раз в сутки).

Запрос (английский): "Lets write simple Space Invaders clone game under BASIC for IBM PC which will work on the earliest one models with 16-48-64 kbytes.I've provide BASIC documentation and sample game in BASIC code.Take a note - .BAS file size limit must be not exceed 16000 bytes. "

Ссылки - Google Gemini 3, Qwen3-Max (правки).

Итоговый код после ряда правок:

10 REM IBM Invaders 
20 DEFINT A-Z:KEY OFF:CLS 
30 SCREEN 1,0:COLOR 3,1 
40 DIM SHIP%(50), ALIEN%(50), MISSILE%(10) 
50 PX=150:PY=180:BX=0:BY=0:BF=0 
60 AD=2:AC=5:SC=0 
70 DIM AX(5),AY(5),AS(5) 
80 CLS:PRINT"" 
90 LINE(0,8)-(8,0),1:LINE-(16,8),1:LINE-(0,8),1:PAINT(8,4),1,1 
100 GET(0,0)-(16,8),SHIP%:CLS 
110 DRAW"BM0,0 D8 R12 U8 L12 M+6,6 M+6,-6":PAINT(2,2),2,3 
120 GET(0,0)-(12,8),ALIEN%:CLS 
130 LINE(0,0)-(2,6),3,BF:GET(2,0)-(0,6),MISSILE%:CLS 
140 WIDTH 40:CLS:LOCATE 8,10:PRINT"IBM INVADERS" 
150 LOCATE 10,8:PRINT"Arrows to Move":LOCATE 11,8:PRINT"Space to Fire" 
160 LOCATE 15,8:PRINT"Press SPACE to Start" 
170 I$=INKEY$:IF I$="" GOTO 170 
180 IF I$<>" " GOTO 170 
190 CLS 
200 FOR I=0 TO AC-1:AX(I)=40+I*50:AY(I)=10:AS(I)=1:NEXT 
210 PUT(PX,PY),SHIP%,PSET 
220 REM Main Loop 
230 K$=INKEY$ 
240 IF K$=CHR$(27) GOTO 900 
250 IF LEN(K$)=2 THEN K$=RIGHT$(K$,1) 
260 IF K$="K" THEN PX=PX-5:IF PX<0 THEN PX=0 
270 IF K$="M" THEN PX=PX+5:IF PX>300 THEN PX=300 
280 IF K$=" " AND BF=0 THEN BF=1:BX=PX+7:BY=PY-5:SOUND 1000,1 
290 PUT(PX,PY),SHIP%,PRESET 
300 IF BF=0 GOTO 350 
310 PUT(BX,BY),MISSILE%,PRESET 
320 BY=BY-32 
330 IF BY<0 THEN BF=0:GOTO 350 
340 PUT(BX,BY),MISSILE%,PSET 
350 M=0 
360 FOR I=0 TO AC-1 
370 IF AS(I)=0 GOTO 430 
380 PUT(AX(I),AY(I)),ALIEN%,PRESET 
390 AX(I)=AX(I)+AD 
400 REM Collision: bullet vs alien 
410 IF BF=1 AND BX+2>=AX(I) AND BX<=AX(I)+12 AND BY+6>=AY(I) AND BY<=AY(I)+8 THEN AS(I)=0:BF=0:PUT(BX,BY),MISSILE%,PRESET:SC=SC+10:SOUND 37+RND*200,2:GOTO 430 
420 PUT(AX(I),AY(I)),ALIEN%,PSET 
430 IF AS(I)=1 AND (AX(I)>300 OR AX(I)<5) THEN M=1 
440 NEXT I 
450 IF M=1 THEN AD=-AD 
460 FOR J=0 TO AC-1 
470 IF AS(J)=1 THEN PUT(AX(J),AY(J)),ALIEN%,PRESET 
480 AY(J)=AY(J)+1:PUT(AX(J),AY(J)),ALIEN%,PSET 
490 NEXT J 
500 LOCATE 1,1:PRINT"SCORE:";SC 
510 IF AY(0)>160 THEN GOTO 950 
520 IF SC=50 THEN CLS:PRINT"YOU WIN!":GOTO 990 
530 FOR D=1 TO 50:NEXT D 
540 GOTO 220 
900 CLS:SCREEN 0:WIDTH 80:SYSTEM 
950 CLS:LOCATE 10,15:PRINT"GAME OVER":SOUND 100,10 
960 FOR I=1 TO 2000:NEXT:GOTO 140 
990 END 
Объяснить код с

Скриншот:

Баги:

- Противники спускаются на один пиксель сразу по осям X и Y.

- Не очищается предыдущая позиция при перемещении на новое место (касается всех объектов - корабля игрока, ракеты и противников).

- Противники при спуске оставляют шлейф.

- Ракета может пролететь мимо противника несмотря на то, что визуально она проходит через его спрайт.

- От ракеты остается полоска после прохождения позиции.

- После попадания противник не стирается полностью: его рамка продолжает падать, но прямо вниз (хотя может выглядеть как визуализация обломков после взрыва).

Костыли:

- Фон в цвете шлейфа.

Что можно было бы исправить:

- Спуск противников по X до конца линии, а потом спуск по Y до достижения конца линии по X.

- Коррекция скорости ракеты, чтобы её линии попадания совпадали с линиями движения противников.

Что можно было бы добавить:

- Жизни.

- Отстрел противниками.

- После первого попадания от противников остаются обломки, которые нужно уничтожать отдельно.

На мой взгляд, исправить баги и получится вполне себе donationware за $4.99, который мог распространяться через BBS или быть опубликован в каком-нибудь журнале в виде листинга.

Скачать - github

Возможные выводы

В целом, несмотря на некоторые неудобства, опыт написания под BASIC на оригинальном конфиге IBM PC образца 1981 года интересный. Сделать нечто динамичное теоретически возможно, особенно если разобраться с нюансами рисования и отображения графики (Donkey хороший пример такого). Понятно, что для чего-то более комплексного потребуется использовать MASM (для сегментов кода, которые нужно обрабатывать быстро, BASIC такое допускает через CALL), а в идеале вовсе писать на C. Однако в 1981 году реализации C под IBM PC еще не было - самые ранние вышли уже в 1982 году, но доступны те, что датируются 1983 годом.

Также, по моим впечатлениям, BASIC похож на Python (построчный синтаксис исполняющийся последовательно, но при этом предусматривающий некоторое распараллеливание операций через GOSUB и GOTO), только проще и по функционалу, и по возможностям.