Компиляция больших QB программ в FB
 

От переводчика: Данная статья устарела. Найти файл, который предлагается для портирования, нет возможности, поскольку сайт уже не существует. Вы можете найти уже адаптированные файлы под старую версию FB , но для компиляции на новой версии, вам придется однозначно править исходные файлы с учетом нововведений FB. Тем не менее, это не помешало мне перевести данную статью на русский язык.

Давайте попробуем составить большую (>4000 строк) графическую программу QB в FreeBASIC, чтобы увидеть, как совместимы FB с QB.
В качестве примера я буду использовать отличный рэйтрейсер с квадратичными и кубическими формами, запрограммированный в 2004 году автором Jark. Вы можете получить TCRay.zip отсюда: http://www.mandelbrot-dazibao.com/Programs/Programs.htm

Обратите внимание, что TCRay является QB4.5 интерпретируемой программой, Jark не желал компилировать свою работу. Он просто проверял свои тесты , дополняя их новыми функциями.


Программа состоит из 3 файлов:

TcRay21C.bas - Главный файл.
TcLib17L.bas - SVGA графическая библиотека.
Tclib17.bi - Включаемый файл для библиотеки.

Портирование TCLib17.bas

В TCLib17.bas
Это «Чисто QB» библиотека SVGA. Большинство его функций являются устаревшими для FB , так как они реализованы в виде ключевых слов QB-стиля. Я имел мою долю в разработке этой библиотеки, так что вы можете доверять мне по этой части ;)

Закомментируйте содержимое процедуры ClearScreen и добавьте это:
CLS

Закомментируйте содержимое процедуры Point24 и добавьте это:
a& = Point(x%,y%)
red% = a& Shr 16
green% = (a& Shr 8) And 255
blue% = a& And 255


Закомментируйте содержимое процедуры Pset24 и добавьте это:
PSet (x%,y%), red% Shl 16 Or green Shl 8 Or blue

Закомментируйте содержимое процедуры Screenshot и добавьте это:
BSave Name$+".bmp"

Закомментируйте содержимое процедуры SelectVga, мы будем работать с фиксированным размером, который большинство PC будет поддерживать. Закомментируйте содержимое процедуры SetText, мы имеем возможность вывода текста в HiRes графике, так что переключение режимов не требуется.

Закомментируйте содержимое процедуры SetVGA, за исключением двух вычислений Powers в конце и добавьте эти четыре строки:
Screen 20,32 '1024x768, 32 bits
scrheight=768
scrwidth=1024
Fullscreen



В TCRay17.bas
Добавьте SetSVGA первой строкой в процедуре Menu (мы не переключаем режимы, режим должен быть установлен перед выводом текста),

Компиляция
OK, теперь вы можете начать попытку компиляции. Вы будете получать некоторые ошибки.

Компилировать так: fbc -s gui -w 1 -lang qb TcRay21C.bas TcLib17L.bas

Я предупреждаю вас все необходимые изменения, за исключением двух приходят от нескольких ограничений в синтаксисе FB:
  • A variable name can't be a keyword plus a type suffix Имя переменной не может быть ключевым словом плюс суффикс типа
  • A simple variable can't have the same name as an array Простая переменная не может иметь то же имя, что массив

В TCLib17.bi
ERROR: Duplicated definition, found 'RGB' (RGB is a keyword in FB) Ошибка: Дублированные определения, найдено «RGB» (RGB является ключевым словом в FB)
Добавьте:
#undefine RGB
Перед строкой, дает ошибку.

ERROR: Duplicated definition, found 'ScreenRes' (ScreenRes is a keyword in FB) Ошибка: Дублированные определения, найдено «ScreenRes» (ScreenRes — это ключевое слово в FB)
Добавьте:
#undefine ScreenRes
Перед строкой, дает ошибку.

ERROR: Duplicated definition, found 'Name' (Name is a keyword in QB) Ошибка: Дублированные определения, найдено «Name» (Name — это ключевое слово в FB)
Добавьте
#undefine Name
Перед строкой, дает ошибку.

In TCRay17.bas
ERROR: Duplicated definition, found 'Acos' (Acos is a keyword in QB) Ошибка: Дублированные определения, найдено «Acos» (Acos — это ключевое слово в FB)
Добавьте
#undefine Acos
Перед строкой, дает ошибку.

ERROR: Argument count mismatch Clear (Clear is not required in FB, the keyword has been reused (not a clever decision?)) ОШИБКА: Несоответствие количества аргументов Clear (Clear не требуется в FB, ключевое слово было повторно (не умное решение)?)
'закомментируйте вашу CLEAR

ERROR: Illegal specification, at parameter 2 (Type) of Init.Cubic() (Type is a keyword in QB) ОШИБКА: Неверное определение в параметре 2 (Type) Init.Cubic () (тип является ключевым словом в QB)
Мы можем переопределить с помощью поиска и замены type$ в _type$

ERROR: Expected 'END IF', found 'END' END FUNCTION Ошибка: Ожидаемый «END IF», найден «END» END FUNCTION
Это ошибка вызвана причудой, введенной в FB. Однострочные If , имеющие двоеточие после THEN требуют ENDIF, это должно делаться с макросами... Какие причины были у Jark поставить двоеточие после THEN , мне непонятно. Они вообще не требуются в QB и FB ведет себя так, как ожидалось без них. Удалите все двоеточия после этого ключевые слова. Поиск и замена THEN :  в THEN

ERROR: Array access, index expected, before '=' xn = x * x - y * y + zx0 Ошибка: Доступ к массиву, индекс, как ожидается, перед '=' xn = x * x - y * y + zx0
У нас есть массив имен xn, и переменная с именем xn. Нужно заменить xn на _xn в линиях где возникает ошибка при компиляции.

Та же ошибка с x0, у нас есть массив под названием x0.
Заменить x0 на _x0 в линиях где ошибка при компиляции.

ERROR: Array access, index expected, before '*' dadY = Amplitude * dAdR * drdY.Ошибка: Для доступа к массиву индекс ожидается перед '*' dadY = Amplitude * dAdR * drdY.
Такая же проблема с Amplitude. Замените Amplitude на _Amplitude в линиях , где ошибка возникает при компиляции.

Хорошо. В этот момент все модули скомпилированы. Теперь мы будем исправлять несколько ошибок компоновщика

Ошибки линкера
После компиляции , компоновщик линкует вместе все модули с библиотекой runtime, и находит окончательные адреса каждой процедуры/функции и замещает поля вызовов этими адресами. Если процедура/функция вызывается в коде и не может быть найдена, компоновщик жалуется и дает нам имя ошибочной функции. Он не может дать нам номер строки (компоновщик не работает с исходником), поэтому мы должны сделать текстовый поиск, чтобы найти, где возникает проблема. Обратите внимание, компоновщик дает нам "подогнанные" имена функций (амперсанд и размер переданных параметров добавляется в конце), просто игнорируйте амперсанд и то, что после.

TcRay21C.o:fake:(.text+0x174d): undefined reference to `LINE24@20'  Необъявленная ссылка на 'LINE24@20'
Вызов неопределенной процедуры Line24 производится в программе, вы можете найти этот вызов внутри Draw.Axis в TCRay21.bas. Процедура никогда не вызывается (вы можете сделать поиск, чтобы убедиться в этом)
Вероятно QB4.5 компилятор будет слишком жаловаться по этому поводу. (Помните: Эта программа никогда не компилировалась в QB4.5) Просто закомментируйте содержимое процедуры Draw.Axis

TcRay21C.o:fake:(.text+0x181b3): undefined reference to `FFIX@0' Необъявленная ссылка на FFIX@0
Ffix был полезным патчем от v1ctor для чисел с плавающей точкой для QB 4.5. Это не требуется в FreeBASIC. Просто закомментируйте строки вызова сразу после объявления в tcray21c.bas

Вот и все, программа компилируется и работает. Немного изменений для 4000+ линий...
Наслаждайтесь!