OberonCore
https://forum.oberoncore.ru/

Внешний модуль / SDL2
https://forum.oberoncore.ru/viewtopic.php?f=34&t=5658
Страница 1 из 1

Автор:  kekc_leader [ Среда, 06 Апрель, 2016 17:00 ]
Заголовок сообщения:  Внешний модуль / SDL2

Добрый день. Изучаю Блэкбокс в качестве замены OO2C, и решил создать привязку к SDL2. Я знаю, что такая привязка уже есть (http://gitlab.molpit.org/bindings/sdl2), но она мне показалась чрезмерно навороченной (для моих целей). Я уже написал свою для VOC и с незначительными изменениями перенёс её на OO2C, хочу теперь перенести на Блэкбокс.

Я установил Blackbox для Линукса отсюда:
http://gitlab.molpit.org/oberon/blackbox-freenix
и решил написать простенький вшнешний модуль привязки к SDL2 (у меня на Дебиане стоит SDL версии 2.0.2).
Минимальный код такого модуля должен позволять инициализировать SDL, создавать окно, создавать прорисовщик, очищать экран, «отображать» его и ждать заданное количество времени.

Я создал подкаталог SDL в каталоге с Блэкбоксом, создал в нём файл SDL.odc:
Н-да, теперь я понял, что из Блэкбокса под Линуксом нельзя скопировать текст модуля... :shock:
Поэтому перываю свой пост, пока мне кто-нибудь не поможет. :D (Когда я копирую с помощью контекстного меню или CTRL+C, буфер обмена не меняется.)

Если коротко, проблема в том, что тестовый модуль вроде как запускает SDL без ошибок и ждёт 2 секунды, но при этом окно SDL не появляется. Просто всё зависает на 2 секунды, а потом отвисает. Это как-то связано с вот этим? (код из уже готовой привязки SDL2)
Код:
SDL* = POINTER TO ABSTRACT RECORD (Kernel.Hook)
  events*: Events;
END;
Мне тоже такое нужно будет или можно обойтись?
Ещё непонятно, как Блэкбокс понимает, что CreateWindow - это именно SDL_CreateWindow. Он сам пытается приписать "SDL_"?
Скомпилировать тот готовый SDL2 на версии Блэкбокса для Линукса тоже не получилось - когда нажимаешь на значок :!: рядом с «To Compile: (!) Dev.Compiler.CompileThis ...», пишет: «Не удалось открыть файл Timer.odc».

Автор:  prospero78 [ Среда, 06 Апрель, 2016 17:24 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

Вполне возможно, что копирование не работает из-за несовпадающих раскладок (например, для копирования <Ctrl+C>, а раскладка русская).
Нужно установить подсистему, в которой есть Timer.odc. Если этот файл прям в подсистеме числится, а его нет -- значит подсистема какая-то кривая.
Ничего Блэкбокс не приписывает. Надо обращаться так, как называется функция либо в подсистеме SDL, либо как эта функция описана в интерфейсном модуле.
Не работаю с SDL, но судя по всему, раз events CREATE не отрабатывается, SDL (видимо) считает, что он всё сделал честно.

Автор:  Роман М. [ Среда, 06 Апрель, 2016 19:00 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

kekc_leader писал(а):
Добрый день. Изучаю Блэкбокс в качестве замены OO2C, и решил создать привязку к SDL2. Я знаю, что такая привязка уже есть (http://gitlab.molpit.org/bindings/sdl2), но она мне показалась чрезмерно навороченной (для моих целей). Я уже написал свою для VOC и с незначительными изменениями перенёс её на OO2C, хочу теперь перенести на Блэкбокс.

Я установил Blackbox для Линукса отсюда:
http://gitlab.molpit.org/oberon/blackbox-freenix
и решил написать простенький вшнешний модуль привязки к SDL2 (у меня на Дебиане стоит SDL версии 2.0.2).
Минимальный код такого модуля должен позволять инициализировать SDL, создавать окно, создавать прорисовщик, очищать экран, «отображать» его и ждать заданное количество времени.

Я создал подкаталог SDL в каталоге с Блэкбоксом, создал в нём файл SDL.odc:
Н-да, теперь я понял, что из Блэкбокса под Линуксом нельзя скопировать текст модуля... :shock:
Поэтому перываю свой пост, пока мне кто-нибудь не поможет. :D (Когда я копирую с помощью контекстного меню или CTRL+C, буфер обмена не меняется.)

Если коротко, проблема в том, что тестовый модуль вроде как запускает SDL без ошибок и ждёт 2 секунды, но при этом окно SDL не появляется. Просто всё зависает на 2 секунды, а потом отвисает. Это как-то связано с вот этим? (код из уже готовой привязки SDL2)
Код:
SDL* = POINTER TO ABSTRACT RECORD (Kernel.Hook)
  events*: Events;
END;
Мне тоже такое нужно будет или можно обойтись?
Ещё непонятно, как Блэкбокс понимает, что CreateWindow - это именно SDL_CreateWindow. Он сам пытается приписать "SDL_"?
Скомпилировать тот готовый SDL2 на версии Блэкбокса для Линукса тоже не получилось - когда нажимаешь на значок :!: рядом с «To Compile: (!) Dev.Compiler.CompileThis ...», пишет: «Не удалось открыть файл Timer.odc».
Особенно перед написанием привязок к сторонним компонентам стоит изучить сначала ББ и платформенные зависимости. С написанием привязок и их использованием есть немало нюансов и сходу их всех не понять. Более того, для консольной версии blackbox-freenix также есть свои нюансы.
Таким образом, я попытался бы сначала отлаживать компоненты, запуская BlackBox.exe (ominc) в wine. Нужно

1. Согласно соглашениям разработки в каноническом ББ необходимо сохранять файлы исходников модулей по такому пути: ПОДСИСТЕМА/Mod/НАЗВАНИЕМОДУЛЯПОДСИСТЕМЫ.odc
Так, модуль Sdl2Events (MODULE Sdl2Events; (*...*) END Sdl2Events.) лежит в Sdl2/Mod/Events.odc

2. Для привязки к библиотеке можно указывать другие имена функциям, умышленно опуская приставки.
Допустим, в модуле Sdl2Core можно создать функцию SDL_CreateWindow. Тогда при использовании функции Sdl2Core.SDL_CreateWindow.
А можно опустить приставку "SDL_" для функции. Тогда вызов будет Sdl2Core.CreateWindow.

3.
Цитата:
Код:
SDL* = POINTER TO ABSTRACT RECORD (Kernel.Hook)
  events*: Events;
END;
Мне тоже такое нужно будет или можно обойтись?
Такой код не нужен. Это дополнительные абстракции.

Автор:  kekc_leader [ Четверг, 07 Апрель, 2016 02:25 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

Спасибо за ответы. Изменил название модулей и разложил правильно по каталогам.
Попробовал скомпилировать этот код на Windows XP, заменил в этой строчке "libSDL2.so" на "SDL2.dll":
Код:
MODULE SDL2Lib ["libSDL2.so"];
Скачал файл SDL2.dll и поместил его в корневой каталог Блэкбокса. Файл качается отсюда: https://www.libsdl.org/download-2.0.php [см. «SDL2-devel-2.0.4-mingw.tar.gz (MinGW 32/64-bit)» в разделе «Development Libraries -> Windows»]

Ещё заменил SDL_RENDERER_ACCELERATED на SDL_RENDERER_SOFTWARE (на виртуальной машине с Виндоусом SDL2 неадекватно обрабатывает отсутствие видеокарты), т. е. заменил {1} на {0} в этой строчке:
Код:
ren := SDL.SDL_CreateRenderer(win, -1, {1});

Запустил, произошло почти тоже самое: Блэкбокс завис на пару секунд (как и написано в тестовой программе - вызывается SDL_Delay(2000)). Единственное отличие от Лиунксовской версии состоит в том, что на эти две секунды в панели программ появляется новое окошко Блэкбокса. Точнее, появляется кнопка (см. прилож. рис.). Если на неё быстро нажать, она типа берёт фокус, но ничего не происходит, само окно не появляется. Почему окно невидимое? Что я забыл сделать? Помню, месяца 4 назад я быстренько сделал в Блэкбоксе на Виндоусе такую же привязку к SDL2 и всё как-то быстро заработало. Потом, кажется, оно стало иногда крэшится и я не мог понять почему (и тогда пришлось найти более понятный OO2C и делать всё в нём).

Кстати, если запустить Блэкбокс на Линуксе из-под Wine (сборка OberonCore), то из него можно будет копировать текст модулей, поэтому привожу текст ниже.
Sdl/Mod/Lib.odc:
Код:
MODULE SdlLib ["libSDL2.so"]; (* А на Винде тут должно быть ["SDL2.dll"] *)

TYPE
   Window* = POINTER TO ABSTRACT RECORD END;
   Renderer* = POINTER TO ABSTRACT RECORD END;

   Version* = RECORD
      major*, minor*, patch*: SHORTCHAR
   END;

PROCEDURE [ccall] SDL_GetVersion*(VAR ver: Version);
PROCEDURE [ccall] SDL_Init*(flags: SET): INTEGER;
PROCEDURE [ccall] SDL_Quit*;
PROCEDURE [ccall] SDL_Delay*(ms: INTEGER);
PROCEDURE [ccall] SDL_CreateWindow*
   (title: ARRAY OF CHAR; x, y, w, h: INTEGER; flags: SET): Window;
PROCEDURE [ccall] SDL_DestroyWindow*(win: Window);
PROCEDURE [ccall] SDL_CreateRenderer*
   (win: Window; index: INTEGER; flags: SET): Renderer;
PROCEDURE [ccall] SDL_DestroyRenderer*(ren: Renderer);
PROCEDURE [ccall] SDL_RenderClear*(ren: Renderer);
PROCEDURE [ccall] SDL_RenderPresent*(ren: Renderer);
PROCEDURE [ccall] SDL_SetRenderDrawColor*
   (ren: Renderer; r, g, b, a: INTEGER);

END SdlLib.

(!) DevCompiler.Compile SdlLib

SDLTest/Mod/SDLTest.odc:
Код:
MODULE SDLTest;

IMPORT StdLog, SDL := SdlLib;

VAR win: SDL.Window;
   ren: SDL.Renderer;

PROCEDURE Draw;
BEGIN
   SDL.SDL_SetRenderDrawColor(ren, 255, 0, 0, 255);
   SDL.SDL_RenderClear(ren);
   SDL.SDL_RenderPresent(ren);
   SDL.SDL_Delay(2000)
END Draw;

PROCEDURE Do*;
BEGIN
   IF SDL.SDL_Init({5}) # 0 THEN
      StdLog.String('Error in SDL_Init'); StdLog.Ln
   ELSE
      win := SDL.SDL_CreateWindow('', 10, 10, 320, 200, {});
      IF win = NIL THEN
         StdLog.String('Error in SDL_CreateWindow'); StdLog.Ln
      ELSE
         ren := SDL.SDL_CreateRenderer(win, -1, {1}); (* Если тут ошибка, то пишем {0}, чтобы переключить на с аппаратного прорисовщика на программный *)
         IF ren = NIL THEN
            StdLog.String('Error in SDL_CreateRenderer'); StdLog.Ln
         ELSE
            Draw;
            SDL.SDL_DestroyRenderer(ren)
         END;
         SDL.SDL_DestroyWindow(win)
      END
   END;
   SDL.SDL_Quit;
   StdLog.String('SDL_Quit successful.'); StdLog.Ln
END Do;

END SDLTest.

(!) DevCompiler.CompileAndUnload SDLTest
(!) SDLTest.Do


Вложения:
Комментарий к файлу: Странная кнопка окна SDL
sdlwindow.png
sdlwindow.png [ 1.8 КБ | Просмотров: 2349 ]

Автор:  Alexander Shiryaev [ Четверг, 07 Апрель, 2016 03:33 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

Правильно так:
Код:
MODULE Sdl2Sdl ["SDL2.dll"];

   CONST
      (* Init flags *)
         initTimer* = 0;
         initAudio* = 4;
         initVideo* = 5;
         initJoystick* = 9;
         initHaptic* = 12;
         initGameController* = 13;
         initEvents* = 14;
         initNoParachute* = 20;
         initEverything* = {
            initTimer,
            initAudio,
            initVideo,
            initEvents,
            initJoystick,
            initHaptic,
            initGameController
         };
      (* Renderer flags *)
         rendererSoftware* = 0;
         rendererAccelerated* = 1;
         rendererPresentVSync* = 2;
         rendererTargetTexture* = 3;

   TYPE
      Uint8* = SHORTCHAR;
      int* = INTEGER;
      char* = SHORTCHAR;
      Uint32* = INTEGER;
      Uint32Flags* = SET;
      PtrStr* = POINTER [untagged] TO ARRAY [untagged] OF SHORTCHAR;
      PtrStrArray* = ARRAY [untagged] OF PtrStr;

      Version* = RECORD [untagged]
         major*: Uint8;
         minor*: Uint8;
         patch*: Uint8
      END;

      Window* = POINTER [untagged] TO WindowDesc;
      WindowDesc* = RECORD [untagged] END;

      Renderer* = POINTER [untagged] TO RendererDesc;
      RendererDesc* = RECORD [untagged] END;

   PROCEDURE [ccall] GetVersion* ["SDL_GetVersion"] (VAR ver: Version);
   PROCEDURE [ccall] Init* ["SDL_Init"] (flags: Uint32Flags): int;
   PROCEDURE [ccall] main* ["SDL_main"] (argc: int; VAR [nil] argv: PtrStrArray): int;
   PROCEDURE [ccall] Quit* ["SDL_Quit"];
   PROCEDURE [ccall] Delay* ["SDL_Delay"] (ms: Uint32);
   PROCEDURE [ccall] CreateWindow* ["SDL_CreateWindow"] (title: PtrStr; x, y, w, h: int; flags: Uint32Flags): Window;
   PROCEDURE [ccall] DestroyWindow* ["SDL_DestroyWindow"] (win: Window);
   PROCEDURE [ccall] CreateRenderer* ["SDL_CreateRenderer"] (window: Window; index: int; flags: Uint32Flags): Renderer;
   PROCEDURE [ccall] DestroyRenderer* ["SDL_DestroyRenderer"] (renderer: Renderer);
   PROCEDURE [ccall] RenderClear* ["SDL_RenderClear"] (renderer: Renderer): int;
   PROCEDURE [ccall] RenderPresent* ["SDL_RenderPresent"] (renderer: Renderer);
   PROCEDURE [ccall] SetRenderDrawColor* ["SDL_SetRenderDrawColor"] (renderer: Renderer; r, g, b, a: Uint8): int;

END Sdl2Sdl.

Код:
MODULE TmpSDLTest;

   IMPORT Log := StdLog, SDL := Sdl2Sdl;

   VAR win: SDL.Window;
      ren: SDL.Renderer;

   PROCEDURE Draw;
      VAR res: SDL.int;
   BEGIN
      res := SDL.SetRenderDrawColor(ren, 0FFX, 0X, 0X, 0FFX);
      res := SDL.RenderClear(ren);
      SDL.RenderPresent(ren);
      SDL.Delay(2000)
   END Draw;

   PROCEDURE Do*;
   BEGIN
      IF SDL.Init({SDL.initVideo}) # 0 THEN
         Log.String('Error in SDL.Init'); Log.Ln
      ELSE
         win := SDL.CreateWindow('', 10, 10, 320, 200, {});
         IF win = NIL THEN
            Log.String('Error in SDL.CreateWindow'); Log.Ln
         ELSE
            ren := SDL.CreateRenderer(win, -1, {SDL.rendererAccelerated});
               (* Если тут ошибка, то пишем {SDL.rendererSoftware},
               чтобы переключить с аппаратного прорисовщика на программный *)
            IF ren = NIL THEN
               Log.String('Error in SDL.CreateRenderer'); Log.Ln
            ELSE
               Draw;
               SDL.DestroyRenderer(ren)
            END;
            SDL.DestroyWindow(win)
         END
      END;
      SDL.Quit;
      Log.String('SDL.Quit successful.'); Log.Ln
   END Do;

END TmpSDLTest.

(^Q) TmpSDLTest.Do

Автор:  Иван Денисов [ Четверг, 07 Апрель, 2016 21:25 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

kekc_leader писал(а):
Я создал подкаталог SDL в каталоге с Блэкбоксом, создал в нём файл SDL.odc:
Н-да, теперь я понял, что из Блэкбокса под Линуксом нельзя скопировать текст модуля... :shock:
Поэтому перываю свой пост, пока мне кто-нибудь не поможет. :D (Когда я копирую с помощью контекстного меню или CTRL+C, буфер обмена не меняется.

Копирование пока работает только между несколькими Блэкбоксами и в него. Не знаю как там организовать копирование наружу пока.

Автор:  Иван Денисов [ Четверг, 07 Апрель, 2016 21:32 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

Проверил на 64 bit Ubuntu 14.04.4. Работает отлично.
Вложение:
test.png
test.png [ 300.61 КБ | Просмотров: 2306 ]


Надо только поставить библиотеку:
Код:
sudo apt-get install libsdl2-2.0-0:i386


Заголовок вот такой:
Код:
MODULE Sdl2Sdl ["libSDL2-2.0.so.0"];

Автор:  kekc_leader [ Пятница, 08 Апрель, 2016 13:03 ]
Заголовок сообщения:  Re: Внешний модуль / SDL2

Alexander Shiryaev писал(а):
Правильно так:
Спасибо! Разобрался. В моём варианте всё портила эта строчка:
Код:
PROCEDURE [ccall] SDL_CreateWindow*(title: ARRAY OF CHAR; x, y, w, h: INTEGER; flags: SET): Window;

Поменял на такую и заработало:
Код:
PROCEDURE [ccall] SDL_CreateWindow*(title: POINTER [untagged] TO ARRAY [untagged] OF SHORTCHAR; x, y, w, h: INTEGER; flags: SET): Window;
Ещё не увидел, что в SDL_SetRenderDrawColor аргументы типа Uint8, а не int.
В других компиляторах Оберона ARRAY OF CHAR работает, но это, видимо, из-за того, что они всё равно транслируют любой код в Си, поэтому сами отлавливают такие случаи и меняют «ARRAY OF CHAR» на «char*».

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/