Например TDA7294

Форум РадиоКот • Просмотр темы - Меню в stm32 & LCD
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Ср дек 10, 2025 22:10:40

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 31 ]  1,  
Автор Сообщение
Не в сети
 Заголовок сообщения: Меню в stm32 & LCD
СообщениеДобавлено: Пн ноя 06, 2023 22:40:47 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Как правильно создать меню на указателях и в чём его суть?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Пн ноя 06, 2023 22:52:27 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
Указатель суть есть адрес вызываемой функции обработчика меню. По нажатию кнопки вызывается соответствующая функция, где уже прописана реакция.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Вт ноя 07, 2023 11:41:56 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Указатель суть есть адрес вызываемой функции обработчика меню. По нажатию кнопки вызывается соответствующая функция, где уже прописана реакция.

вы имеете ввиду что на любую кнопку нужна функция?Или как?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Вт ноя 07, 2023 12:06:33 
Друг Кота

Карма: 67
Рейтинг сообщений: 1964
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
если подобное условие возникло, то это и есть суть - решение этого условия.
как правильно программировать - слишком общий вопрос


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Вт ноя 07, 2023 12:33:56 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
ioan dobrev писал(а):
на любую кнопку нужна функция

На любое состояние нужна функция. Наверное, проще будет показать пример. Попозже старый проект отрою.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Вт ноя 07, 2023 20:48:57 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Ну если можете покажите пример .И как допустим одна кнопка допустим в режиме UP и "+".

Добавлено after 2 minutes 4 seconds:
И любое состояние функция .И вывод информации.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Вт ноя 07, 2023 21:53:43 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 8
Тэээк-с, ну допустим. Вот один из вариантов реализации. Оно было скорее как эксперимент, но тем не менее.

Итак. Во-первых, надо объявить тип, который будет отвечать за один элемент меню.
Код:
typedef struct menuitem {
   char      name[17];  //выводимое имя пункта
   int32_t      min;          //минимальное значение параметра, который настраивается в меню
   int32_t      max;         //максимальное значение
   int32_t      value;       //текущее значение, Меняется кнопками "вверх" и "вниз"
   int32_t      oldvalue;  //значение до сохранения
   int32_t      step;          //шаг изменения значения
   struct   menuitem   *left;           //соседнее меню слева
   struct   menuitem   *right;        //соседнее меню справа
   int32_t (* action)();                          //действие пункта меню. Может быть как просто применение текущего значения параметра, так и целая подпрограмма.
   uint8_t      id;                           //просто номер
   } menuitem;


Далее описываются конкретные пункты. Для каждого пункта прописываются все эти поля. То есть громкость, допустим, регулируется от 5 условных единиц до 100 с шагом 5. Тогда переменная volume типа menuitem должна иметь volume.min=5, volume.max=100, volume.step=5. Ну и так далее со всеми элементами.
Код:
menuitem mainmenu={{0x41, 0xBC, 0xBE, 0xBB, 0xB8, 0xBF, 0x79, 0xE3, 0x61, 0x20, 0x79, 0xE3, 0x61, 0x70, 0x61, 0x3A, 0x00}, 0, 65000, 0, 0, 0, NULL, NULL, NULL, 0};
menuitem cortres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x4B, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 0, 100000, 5000, 5000, 100, NULL, NULL, NULL, 1};
menuitem voltres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x48, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 1, 4000, 500, 500, 50, NULL, NULL, NULL, 2};
menuitem blanktime={{0x42, 0x70, 0x65, 0xBC, 0xC7, 0x20, 0xB4, 0xBB, 0x79, 0x78, 0x6F, 0xBF, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1000, 30, 30, 1, NULL, NULL, NULL, 3};
menuitem dynamic={{0xE0, 0xB8, 0xBD, 0x61, 0xBC, 0xB8, 0xBA, 0x61, 0x20, 0xB8, 0xB4, 0x70, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1, 0, 0, 1, NULL, NULL, NULL, 4};
menuitem channels={{0x4B, 0x61, 0xBD, 0x61, 0xBB, 0x6F, 0xB3, 0x20, 0xB3, 0x78, 0x6F, 0xE3, 0x61, 0x3A, 0x20, 0x20, 0x20}, 1, 2, 1, 1, 1, NULL, NULL, NULL, 5};
menuitem learn={"Start learning? ", 0, 1, 0, 0, 1, NULL, NULL, NULL, 6}; //запас
menuitem soundsample={"Sound sample №:", 0, 1, 0, 0, 1, NULL, NULL, NULL, 7};
menuitem *curitem;

Curritem это, собственно, текущий активный элемент меню.
Далее описываем необходимые функции для каждого пункта меню. У меня эти функции вызывается по нажатию на кнопку ОК. Например
Код:
int32_t save()
{
   curitem->oldvalue=curitem->value;
   FramStoreValue(curitem->value, curitem->id);
   LedOn(3, 1000);
   return 0;
};

Вот эта функция выполняет сохранения выбранного значения во внешнюю энергонезависимую память и зажигает красный светодиод на секунду.
И так любые функции, которые надо выполнять по нажатию кнопки ОК.
Дальше начинается само формирования структуры меню. Само меню не древовидное, а в виде двусвязного списка. А можно и ещё связей добавить, сколько хватит кнопок и фантазии. То есть, для, так сказать, главного экрана присваиваем соответствующим полям ссылки на прочие элементы меню. Остальные поля не назначаются, поскольку прочих функций там не предусмотрено.
Код:
mainmenu.left=&cortres;
mainmenu.right=&blanktime;


И для всех остальных та же
Код:
cortres.left=&channels;
cortres.right=&blanktime;
cortres.action=&save;
cortres.oldvalue=FramLoadValue(cortres.id);
cortres.value=cortres.oldvalue;

blanktime.right=&dynamic;
blanktime.left=&cortres;
blanktime.action=&save;
blanktime.oldvalue=FramLoadValue(blanktime.id);
blanktime.value=blanktime.oldvalue;

И так далее для всех прочих пунктов. На этом же этапе происходит загрузка ранее сохранённых значений. Проверки нет, но было бы неплохо это предусмотреть. Ну да ладно, это дело завтрашнего дня.
Ну и собственно, антидребезг и реакция на каждую кнопку. Можно это дело хоть в прерывания засунуть. Для кнопок влево и вправо предусмотрено просто переключение пунктов, вверх и вниз изменяют параметры, ОК чаще всего просто сохраняет и применяет параметры, ВЫХ не делает ничего, просто возвращает в главное меню.
Код:
   while(millis<presstime+PRESSDELAY){};      //антидребезг
   delay(100);
   if(up()){
      curitem->value+=curitem->step;
      if(curitem->value > curitem->max){curitem->value = curitem->max;};
      presstime=millis;
      redraw=1;
      };
   if(down()){
      curitem->value-=curitem->step;
      if(curitem->value < curitem->min){curitem->value = curitem->min;};
      presstime=millis;
      redraw=1;
      };
   if(ok()){
      curitem->action();
      };
   if(esc()){
      curitem->value=curitem->oldvalue;
      curitem=&mainmenu;
      redraw=1;
      };
   if(left()){
      curitem->value=curitem->oldvalue;
      curitem=curitem->left;
      redraw=1;
      };
   if(right()){
      curitem->value=curitem->oldvalue;
      curitem=curitem->right;
      redraw=1;
      };

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

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Вт ноя 07, 2023 22:06:42 
Друг Кота

Карма: 67
Рейтинг сообщений: 1964
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
>TEHb< писал(а):
Во-первых, надо объявить тип, который будет отвечать за один элемент меню.
Точнее, за каждый элемент. И это и есть ответ на вопрос
ioan dobrev писал(а):
в чём его суть?
. И чтобы окончательно понять преимущество такого подхода, необходимо изучить, что есть ООП (объектно-ориентированное программирование).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Ср ноя 08, 2023 19:46:35 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
ООП-а что это такое и с чем его едят.А то у меня меню какое то примитивное хочется пограммотнее


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Ср ноя 08, 2023 20:06:04 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
Ну типа каждый пункт меню это такой объект со своими свойствами и функциями.
Да пофигу, код-то вполне С-шный.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 10:30:05 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Меня заинтересовал 1 код и 2 код.Вопрос 1 структура есть а в структуре есть две структуры .А что в этих структурах?.2 код Это пункты меню? В скопках что указано код для регулировки ? Или что А где же вывод на экран?

Добавлено after 7 minutes 33 seconds:
Код:
menuitem mainmenu={{0x41, 0xBC, 0xBE, 0xBB, 0xB8, 0xBF, 0x79, 0xE3, 0x61, 0x20, 0x79, 0xE3, 0x61, 0x70, 0x61, 0x3A, 0x00}, 0, 65000, 0, 0, 0, NULL, NULL, NULL, 0};
menuitem cortres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x4B, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 0, 100000, 5000, 5000, 100, NULL, NULL, NULL, 1};
menuitem voltres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x48, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 1, 4000, 500, 500, 50, NULL, NULL, NULL, 2};
menuitem blanktime={{0x42, 0x70, 0x65, 0xBC, 0xC7, 0x20, 0xB4, 0xBB, 0x79, 0x78, 0x6F, 0xBF, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1000, 30, 30, 1, NULL, NULL, NULL, 3};
menuitem dynamic={{0xE0, 0xB8, 0xBD, 0x61, 0xBC, 0xB8, 0xBA, 0x61, 0x20, 0xB8, 0xB4, 0x70, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1, 0, 0, 1, NULL, NULL, NULL, 4};
menuitem channels={{0x4B, 0x61, 0xBD, 0x61, 0xBB, 0x6F, 0xB3, 0x20, 0xB3, 0x78, 0x6F, 0xE3, 0x61, 0x3A, 0x20, 0x20, 0x20}, 1, 2, 1, 1, 1, NULL, NULL, NULL, 5};
menuitem learn={"Start learning? ", 0, 1, 0, 0, 1, NULL, NULL, NULL, 6}; //запас
menuitem soundsample={"Sound sample №:", 0, 1, 0, 0, 1, NULL, NULL, NULL, 7};
menuitem *curitem;

Вот этот пункт. А также последняя строка.

Добавлено after 15 minutes 33 seconds:
Код:
int32_t save()
{
   curitem->oldvalue=curitem->value;
   FramStoreValue(curitem->value, curitem->id);
   LedOn(3, 1000);
   return 0;
};

Указатель без"&" ,будет ли он работать.И функция внутри функции а где она?

Добавлено after 8 minutes 52 seconds:
Код:
cortres.left=&channels;
cortres.right=&blanktime;
cortres.action=&save;
cortres.oldvalue=FramLoadValue(cortres.id);
cortres.value=cortres.oldvalue;

blanktime.right=&dynamic;
blanktime.left=&cortres;
blanktime.action=&save;
blanktime.oldvalue=FramLoadValue(blanktime.id);
blanktime.value=blanktime.oldvalue;

Я не спец по указателям по меню.Вот эти две структуры я не вижу.

Добавлено after 14 minutes 31 second:
Код:
mainmenu.left=&cortres;
mainmenu.right=&blanktime;

И вот разименование структуры элемента .А где сами структуры.
Код:
struct
{
   volatile uint16_t Ua;
   volatile  uint16_t Ub;
   volatile  uint16_t Uc;
   volatile  uint16_t Ia;
   volatile  uint16_t Ib;
   volatile  uint16_t Ic;
}par,*par_p;
   par_p=&par;
   

или я не так понимаю .Это мой пример.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 10:35:33 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
>TEHb< писал(а):
   struct   menuitem   *left;           //соседнее меню слева
   struct   menuitem   *right;        //соседнее меню справа

Вот это? Это не сами структуры, это лишь поле, содержащее ссылку на другой элемент того же типа. Указатель. По факту просто адрес другого экземпляра структуры. Собственно, в этом и заключается
ioan dobrev писал(а):
меню на указателях




ioan dobrev писал(а):
В скопках что указано

ioan dobrev писал(а):
{0x41, 0xBC, 0xBE, 0xBB, 0xB8, 0xBF, 0x79, 0xE3, 0x61, 0x20, 0x79, 0xE3, 0x61, 0x70, 0x61, 0x3A, 0x00}

Вот это? Это поле
>TEHb< писал(а):
char      name[17];  //выводимое имя пункта

А в шестнадцатеричном виде потому что это номера кириллических символов в знакосинтезирующем экранчике 1602. А сам вывод это совершенно отдельная независимая функция. Она берёт значения из curitem и выводит уже их.
А вот сам *curitem это ссылка на текущий пункт меню. И эта ссылка подменяется по мере надобности.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 10:46:25 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Ну хорошо я как аматор спрошу вас.Вот эта строчка.
Код:
cortres.right=&blanktime;

Я имею ввиду с правой стороны что это функция или переменная? если переменная то у меня.
Код:
/nastroyki.flag_obriv_a=&c;

Пишет Cubeide ошибку.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 10:57:14 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
Справа это фактически указатель на пункт меню (структура) blanktime. То есть даже и не переменная как таковая, а адрес в памяти. Чтобы такое присвоение получалось элемент right структуры menuitem объявлен как
Код:
struct   menuitem   *right;

То есть мы сразу говорим, что это ссылка на структуру типа menuitem. Потом берём blanktime, который имеет тип menuitem, и присваиваем его адрес полю right.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 11:04:34 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Код:
char      name[17];

Так это у вас буфер Для LCD?.
А то пункты меню?.Но я не увидел Какие кнопки какие уменьшают или увеличивают параметры в меню?Покажите.Если это буфер то как он выводит пункты меню?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 11:16:02 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
Функция вывода на экран это совершенно отдельная независимая функция. К организации меню она не относится. name это по сути просто строка с выводимым названием меню.
ioan dobrev писал(а):
какие уменьшают или увеличивают параметры в меню

Так вот же:
>TEHb< писал(а):
   if(up()){
      curitem->value+=curitem->step;
      if(curitem->value > curitem->max){curitem->value = curitem->max;};
      presstime=millis;
      redraw=1;
      };

Если каким-либо способом пришла команда на увеличение параметра (кнопка, ДУ, генератор случайных чисел, не столь важно), то происходит увеличение value в указанных пределах с указанным шагом. Конкретно в данном случае функция UP проверяет состояние ножки. Так что кнопки одновременно нажимать в таком алгоритме нельзя. Но правильный опрос кнопок это опять-таки отдельная задача.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 11:34:59 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Код:
UP - верх .Doun- вниз

Это шагаете вниз и вверх? А допустим есть какой то параметр G в меню как бы вы записали G++; G--?.А эти символы .Покажите как вы выводите на LCD?Много вопросов.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 11:51:37 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
ioan dobrev писал(а):
какой то параметр G

Объявил бы ещё одну переменную menuitem Gtune и уже внутри неё Gtune.value и устанавливал. И в любом месте программы где надо было бы использовать это значение уже брал бы Gtune.value .
ioan dobrev писал(а):
Покажите как вы выводите на LCD?

Так это же вообще отдельная задача. Ну вот так
Код:
      utoa(curitem->value, string2, 10);
      stringlenght=0;
      while(string2[stringlenght]){stringlenght++;};
      for(stringcounter=16; stringcounter>=0; stringcounter--)
         {
         if (stringlenght>=0){string2[stringcounter]=string2[stringlenght]; stringlenght--;}
         else {string2[stringcounter]=20;};
         };
      LCD1602_PrintStringOfPosition(0, curitem->name);
      LCD1602_PrintStringOfPosition(16, string2);

Вначале преобразование числа в десятичную строку, потом что-то про выравнивание строк или вроде того. Не помню уже. А потом вывод библиотечной функцией. Первой строкой название пункта меню (то самое поле name), а второй строкой текущее значение параметра.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 12:00:13 
Открыл глаза

Зарегистрирован: Вт сен 19, 2023 07:07:05
Сообщений: 72
Рейтинг сообщения: 0
Код:
utoa
а sprintf как вывести.?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Меню в stm32 & LCD
СообщениеДобавлено: Чт ноя 09, 2023 12:04:01 
Друг Кота
Аватар пользователя

Карма: 17
Рейтинг сообщений: 464
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 5550
Откуда: Воронеж
Рейтинг сообщения: 0
Не имею ни малейшего понятия.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 31 ]  1,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y