Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Мультимедиа
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 25.07.2018, 21:41
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию UFmod. Подключение в отдельном модуле и проигрывание

Приветствую.
Скачал я примерчик вот отсюда http://www.delphisources.ru/pages/so...ear/ufmod.html
Всё работает.
Но вопрос такой:
Можно ли код мелодии вынести в отдельный файл и подключать аля
uses или #includ
А то километры этого байт кода в начале кода ну очень не удобно!

И в файл с каким расширением эту музыку засунуть можно ( *pas ?)

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
const
   xm : array[0..130410] of byte = (
	$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,    
.....
.....   
.....  Куча  куча километровых данных
.....
.....
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$03, $03, $03, $03, $03, $02, $03, $02, $03, $02, $02
);

implementation

{$R *.dfm}
//Подключаем файл импорта функций ufmod
{$I ufmod.inc *** uFMOD API (WINMM) }
procedure TForm1.Button1Click(Sender: TObject);
begin
 uFMOD_PlaySong(@xm,Length(xm),XM_MEMORY);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 uFMOD_StopSong;
end;

end.

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

Последний.
Можно как нибудь программно узнать сколько программа проиграла этого байт кода?
И вывести это число в байтах куда нить в Label ?
Спасибо.

Последний раз редактировалось TEKTON, 25.07.2018 в 21:46.
Ответить с цитированием
  #2  
Старый 25.07.2018, 22:05
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Вынести можно,тогда переместите массив ХМ в отдельный юнит через uses, кстати, это не код, это набор байтов сиречь треккерная пестня в формате *.xm "записанная" текстом. Библитотека очень старая,обычно лежит в ресурсах,регулировок у неё вроде нет окромя воспроизведения,паузы и стопа, можно или файлы крутить или потоки, для этого передаются специальные флажки, крутит она не только *.xm, но и *.mod тоже, кажись и *.it берёт с *.s3m`мами, многие крякалки с "музикальными эффектами" используют именно её, bass с регулировками, но она довольно большая по размеру
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
TEKTON (25.07.2018)
  #3  
Старый 25.07.2018, 22:08
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,048
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

1. Можно.
1а) вынести описание в отдельный модуль и подключать его через uses
1б) вынести только декларацию массива в отдельный файл и подключать его через директиву include ( {$I filename.inc} )
1в) положить данные в ресурс, прикомпилировать ресурс в программу и потом просто его считать
1г) просто положить данные в файл рядом с программой и считывать его в память когда надо проиграть

2 и 3 - вопрос к библиотеке. смотри какие функции есть в ufmod.inc
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
TEKTON (25.07.2018)
  #4  
Старый 25.07.2018, 22:21
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию

Спасибо.
Да я знаю что это массив , просто так обозвал не очень удачно

А можно подробнее что оставить в файле окромя массива?
И как это должно выглядеть. (что должно быть в заголовке перед массивом).
Если можно кодом и примером по пунктам 1а), 1в)


С пунктом 1б) разобрался
Оставляем чисто:
Код:
const
   xm : array[0..130410] of byte = (
    $45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,
.....   
.....  Куча  куча километровых данных
.....
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$03, $03, $03, $03, $03, $02, $03, $02, $03, $02, $02
);

А в файле куда подключаем

Код:
{$R *.dfm} 
{$I MUSIC2.inc}

Музыку хочу хранить/таскать внутри самого exe (не рядом с программой).

А что насчёт счётчика масива ?
Можно это организовать как то?

Дело вот в чём.
Просто иногда какой музончик из кейгена надо рипнуть.
Начало музыки найти легко обычно (Extended Module: ...), а вот окончание...
Приходится крамсать с конца файла блоками, пока не нащупаешь окончание музыки.

А так бы было здорово.
Нашёл начало музла, отрезал всё лишнее что перед ним, потом засунул в проигрыватель, прослушал до конца воспроизведения музыки.
А в лейбле отобразилось место до которого надо откромсать файл.
Спасиб.

Последний раз редактировалось TEKTON, 25.07.2018 в 22:53.
Ответить с цитированием
  #5  
Старый 26.07.2018, 11:17
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию

Вот полезный материал для работы с uFMODOM
http://ufmod.sourceforge.net/Example.../commands.html
Может кому тоже пригодится

Последний раз редактировалось TEKTON, 28.07.2018 в 22:52.
Ответить с цитированием
  #6  
Старый 26.07.2018, 21:44
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,048
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну вот прямо так и режешь:

Файл Music1.inc
Код:
const
   xm : array[0..130410] of byte = (
    $45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,    
.....
.....   
.....  Куча  куча километровых данных
.....
.....
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$03, $03, $03, $03, $03, $02, $03, $02, $03, $02, $02
);

В оригинальном исходнике:
Код:
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;

{$I Music1.inc}
 
implementation
 
{$R *.dfm}
//Подключаем файл импорта функций ufmod
{$I ufmod.inc *** uFMOD API (WINMM) }
procedure TForm1.Button1Click(Sender: TObject);
begin
 uFMOD_PlaySong(@xm,Length(xm),XM_MEMORY);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
 uFMOD_StopSong;
end;
 
end.

Т.е., по сути, с точки зрения компилятора исходник остается точно таким же. Просто теперь препроцессор скомпонует его из 2х физических файлов, вставив .inc файл прямо вмето директивы включения.

ЗЫ. Для особо умных. я знаю, что у паскаля нет выделенного шага препроцессора, но так легче объяснить.
Ответить с цитированием
  #7  
Старый 28.07.2018, 18:29
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию

А как проиграть из ресурса xm ?
Почитал о функциях его вот тут http://ufmod.sourceforge.net/Example.../commands.html

Но некоторые коды у меня не работают.
Может мне какая урезанная версия uFmod досталась...

Не работает:
Function uFMOD_PlayFile,
Function uFMOD_PlayMem,
Function uFMOD_PlayRes
...

Работают тока:
Function uFMOD_PlaySong, (Этой кстати нет в том хелпе на который ссылку привёл. Может у меня какая старая версия uFmod*а ).
Function uFMOD_Pause,
Function uFMOD_Resume,
Function uFMOD_Stop.

Слышал что кроме uFmod есть ещё mimiuFmod.
Где можно его скачать ?

И вообще может кто знает, что лучше выбрать

Fmod,
miniFmod,
uFmod,

...
Какие может ещё есть библиотеки для трекерной музыки ?
Может есть всеядные ? (it, xm, mod, S3M)
Которые весят мало-мало...
Если можно микро обзор от тех кто пользовался ими.

Спасибо.

Последний раз редактировалось TEKTON, 28.07.2018 в 23:21.
Ответить с цитированием
  #8  
Старый 28.07.2018, 20:33
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Ну вот прямо так и режешь:

Файл Music1.inc
Код:
const
   xm : array[0..130410] of byte = (
    $45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,    
.....
.....   
.....  Куча  куча километровых данных
.....
.....
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$45, $78, $74, $65, $6E, $64, $65, $64, $20, $4D, $6F, $64, $75, $6C,  
$03, $03, $03, $03, $03, $02, $03, $02, $03, $02, $02
);

В оригинальном исходнике:
Код:
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;

{$I Music1.inc}
 
implementation
 
{$R *.dfm}
//Подключаем файл импорта функций ufmod
{$I ufmod.inc *** uFMOD API (WINMM) }
procedure TForm1.Button1Click(Sender: TObject);
begin
 uFMOD_PlaySong(@xm,Length(xm),XM_MEMORY);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
 uFMOD_StopSong;
end;
 
end.

Т.е., по сути, с точки зрения компилятора исходник остается точно таким же. Просто теперь препроцессор скомпонует его из 2х физических файлов, вставив .inc файл прямо вмето директивы включения.

ЗЫ. Для особо умных. я знаю, что у паскаля нет выделенного шага препроцессора, но так легче объяснить.

Нее.
Я наверно не совсем доходчиво изложил мыслю свою.

Если это наш файл, то да, зная с каких "байт" он начинается и каким заканчивается, можно в Hex вырезать что угодно.
Но это зная "с каких "байт" он начинается и каким заканчивается".

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

Если б трекерная музыка начиналась с определённого заголовка аля
Extended Module: ... и заканчивалась на определённые байты типо как теги в html то было б круто.
Почему такое не было принято не понятно.
Скорее всего просто никого не волновало "выдирание" музыки обратно с уже скомпиленного exe.
А так получается заголовок Extended Module в Hex редакторе можно найти, а где музыка заканчивается, только по "рисунку" и характерным повторениям байтов можно на вскидку определить.
Вот и посетила меня идея что б скрестить трекер плеер с Hex редактором
Что б типо такого получилось:
https://youtu.be/vFx6xNsNQMg
Показанное в ролике, это конечно чудеса монтажа

Типо открываешь в проге exe, она находит начало музыки,
Потом запускаешь плеер и прослушиваешь трек до конца.
Когда музыка остановилась,
кликаешь кнопку и конечный адрес найден.
Ну и что б можно было немного по этим байтам прогуляться было, Вперёд/назад.
Ну и можно сразу резак прикрутить, что б потом в Hex редактор не лазить.
Вот такой мысел

Последний раз редактировалось TEKTON, 29.07.2018 в 08:00.
Ответить с цитированием
  #9  
Старый 29.07.2018, 13:18
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Каждый формат треккерной музыки имеет свои сигнатуры, вот по ним поиск и нужно вести в екзешнике, но правда, не всегда крякалки содержат мелодии не всжатом виде, когда-то тоже пытался выдирать их оттудова, часто не получалось, они были под компрессором, а без алгоритма сжатия что-то вытащить невозможно. Вот процедура что "записывает" пестни текстом в *.pas
Код:
procedure Track2Pas(trcNm, pasNm: string);
var
 f: file;
 txt: text;
 b,c: byte;
 s: string;
begin
 AssignFile(f, trcNm);
 {$I-} Reset(f, 1); {$I+}
 if IOResult = 0 then
  begin
   AssignFile(txt, pasNm + '.pas');
   {$I-} Rewrite(txt); {$I+}
   if IOResult = 0 then
    begin
     Writeln(txt,'unit ' + pasNm + ';');
     Writeln(txt, 'interface');
     Write(txt, 'const  xm: array[1..', FileSize(f),'] of byte = (');
     c:= 0;
     while not EOF(f) do
      begin
       BlockRead(f,B,1);
       Str(b, s);
       if FileSize(f) <> FilePos(f) then s:= s + ',';
       c:= c + length(s);
    Write(txt, s);
    if C > 40 then
     begin
     if FileSize(f) <> FilePos(f) then
     begin
      Writeln(txt);
      Write(txt,'                                             ');
     end;
     C:= 0;
    end;
   end;
   Writeln(txt, ');');
   Writeln(txt, 'implementation');
   Writeln(txt, 'end.');
   CloseFile(txt);
  end;
  CloseFile(f);
 end;
  end;
вдруг подойдет, хотя это и лишне, поскольку сабжевая библиотека может играть просто файл, без преобразований
Ответить с цитированием
  #10  
Старый 29.07.2018, 14:30
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию

Сжатые простыми компрессорами файлы можно не распаковывать.
Просто запускаем, потом каким нить Pe Tools*ом или LordPe снимаем дамп процесса потом в Win Hex и вуаля.
А вот с протами, которые и память шифруют виртуальную вот там да, тока снимать защиту.

А насчёт uFmod*а, странно как то...
Что вставка в сам exe*шник музыки есть, а в ресурс нету.
Неужели авторам было так лень реализовать три функции (из файла рядом с exe, из ресурса, и из самого exe).

Последний раз редактировалось TEKTON, 29.07.2018 в 18:51.
Ответить с цитированием
  #11  
Старый 29.07.2018, 23:02
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от TEKTON
...Что вставка в сам exe*шник музыки есть, а в ресурс нету...
Вообще то есть, считывание из ресурса посредством вызова uFMOD_PlayRes(), как раз в dll и есть три возможности играть из файла, либо ресурса или из памяти, даже регулировка громкости оказывается поканальная есть, и перемотка аля перескок через целый паттерн наблюдается с выводом авторского комента и позиции воспроизведения, забыл, крутит правда она только треки в формате *.xm, но легко другие форматы конвертировать в него через напр. OpenMT
Ответить с цитированием
  #12  
Старый 30.07.2018, 02:01
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Сразу не заметил
Цитата:
Сообщение от TEKTON
...Но некоторые коды у меня не работают.
Может мне какая урезанная версия uFmod досталась...

Не работает:
Function uFMOD_PlayFile,
Function uFMOD_PlayMem,
Function uFMOD_PlayRes
...

Работают тока:
Function uFMOD_PlaySong, (Этой кстати нет в том хелпе на который ссылку привёл. Может у меня какая старая версия uFmod*а ).
Function uFMOD_Pause,
Function uFMOD_Resume,
Function uFMOD_Stop...
И не будут работать, поскольку файл импорта (ufmod.inc) их описания не содержит, а вот тамошняя uFMOD_PlaySong как раз инкаспулирует в себе их всех сразу, просто нужно передавать в неё нужные значения в соответствии с ейной орфографией, напр., чтоб файло проиграть, нужно делать примерно так
Код:
var
fn: string;
begin
 fn:= 'some.xm';
 uFMOD_PlaySong(Pointer(fn), 0, XM_FILE);
end;
с ресурсом тоже самое: сначало необходимо создать *.res файл с мелодией, тысячи примеров у нас на форуме про то, как это делать есть, главное чтоб она обязательно под типом RT_RCDATA лежала, подключить его к проекту, а дальше, с ключом XM_RESOURCE так же в функцию передаётся имя ресурса как и имя файла, поинтером

З.Ы. Ну и вдруг если время воспроизведения потребуется, то тогда можно сделать примерно так: кинуть на форму таймер и лейбл, последним добавить вот такое
Код:
function LenPlay(ds: integer): string;
var
 hour, min, sec: integer;
begin
 ds:= ds div 1000;
 min := ds div 60;
 hour:= min div 60;
 if min > 60 then min:= min mod 60;
 sec := ds mod 60;
 Result:= FormatDateTime('h:mm:ss', EncodeTime(hour, min, sec, 0));
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 label1.Caption:= LenPlay(uFMOD_GetTime);
end;

Последний раз редактировалось Alegun, 30.07.2018 в 02:10.
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
TEKTON (30.07.2018)
  #13  
Старый 30.07.2018, 09:49
TEKTON TEKTON вне форума
Новичок
 
Регистрация: 14.03.2011
Сообщения: 60
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Вообще то есть, считывание из ресурса посредством вызова uFMOD_PlayRes(), как раз в dll и есть три возможности играть из файла...
Начинаю печатать uFMOD_PlayRes, а внизу в строке пишет : "[Error] uFmod.pas(78): Undeclared identifier: 'uFMOD_PlayRes'".
Естественно о праметрах вообще речь не заходит.
Если можно чётко, с примерами эти три "возможности" расписать.

Цитата:
И не будут работать, поскольку файл импорта (ufmod.inc) их описания не содержит
Вот это и странно. Почему не добавить нормальное описание? Всё не для людей...

Цитата:
...а дальше, с ключом XM_RESOURCE так же в функцию передаётся имя ресурса как и имя файла, поинтером
Код:
{$R *.dfm}
{$R MYRES.RES}{Музыка Mus.xm в файл ресурса добавлена, файл подключен}
{$I ufmod.inc *** uFMOD API (WINMM)}

procedure TForm1.BitBtn1Click(Sender: TObject);
var
fn,tip: string;
begin

fn:='MUS';
tip:='RT_RCDATA';
uFMOD_PlaySong(Pointer(fn),Pointer(tip),XM_RESOURCE);
{Так ошибку выдаёт Incompatible types: 'Integer' and 'Pointer'}
end;

И так тоже не пашет
Код:
uFMOD_PlaySong(Pointer(fn),RT_RCDATA, XM_RESOURCE);
Ошибка Incompatible types: 'Integer' and 'PAnsiChar'

Вот в MiniFMOD , это реализовано "по человечески".
Код:
XMLoadFromFILE('MUS.xm');//из файла
XMLoadFromRes('MUS', 'RT_RCDATA');//Из ресурса
{И никаких "танцев с бубном"}

Вернёмся снова к uFmod (Надо его было назвать UFffffmod... )
Когда становлюсь на имя функции и ctrl+клик, переносит на функцию (ufmod.inc)
Код:
function uFMOD_PlaySong(
	lpXM: Pointer;
	param, fdwSong: Integer):
	Integer; stdcall; external;
Чуть выше закомментировано описание Param
Цитата:
param
Handle to the executable file that contains the resource to be
loaded or size of the image of the song in memory. This parameter
is ignored unless XM_RESOURCE or XM_MEMORY is specified in fdwSong.

Музыка MUS.xm в порядке.
Проигрывается из файла и из самого EXE, так что с форматом там всё ок.

P.S. На Ваш взгляд, какая вообще библиотека самая привлекательная?
В плане
1) увеличение файла от её использования,
2) Функционал
3) Удобность кодинга

Может новые библы какие появилися ?
Или только эти Fmod, miniFmod, uFmod?

Последний раз редактировалось TEKTON, 30.07.2018 в 12:13.
Ответить с цитированием
  #14  
Старый 30.07.2018, 22:31
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

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

З.Ы. Есть ещё крутилка bassMod ~ 30Kb весит

Последний раз редактировалось Alegun, 01.08.2018 в 07:14.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:40.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter