Приветствую всех в этой теме.Я хочу вас научить редактировать и создавать свои скрипты для gfxboot формата inc.
Вам известно, что inc скрипты отвечают за многие вещи в вашей теме, так давайте разберём некоторые из них.
Quote (BEGFRAET)
Правила этой темы включают:
1.Разрешается Давать inc код в bbcod [code] [\code]
2. Запрещается создавать ответ с такими словами как спасибо, пожалуйста, и. т. Д. Но комментировать статьи и задавать вопросы – разрешено ! 3. Также чтоб дать ответ или задать вопрос надо выполнить д. з. из урока Я снимаю это правило (Оно глупое)!
Для создателей уроков
4. Надо создавать грамотный материал (т. Е. без ошибок) и в конце каждого урока создавать своё домашнее задание по вашей теме. 5. Запрещается создавать материал не по теме: “Редактирования и создание inc скриптов”.
Описание языка, используемого в скриптах для gfxboot
Файлы с расширением ".inc"(включение) представляют собой шаблоны (текстовые), написанные на языке типа PHP, созданном специально для веб-программирования. Синтаксис очень напоминает синтаксис языка C и во многом заимствован из таких языков как Java и Perl.
Quote
В принципе, в PHP есть практически все операторы и функции, имеющиеся в стандартном GNU С (или их аналоги), например есть циклы (while, for), операторы выбора (if, switch), функции работы с файловой системой и процессами (fopen, *dir, stat, unlink, popen, exec), функции ввода-вывода (fgets,fputs,printf) и множество других...
Синтаксис PHP ----------------------------------------------------------- В файле button.inc расписаны параметры "кнопок", такие, как размеры, местоположение и т.п.. Диалоги, соответствующие назначениям этих "кнопок" и надписи на них прописаны в файлах "ru_RU.tr" и "en.tr" для русского и английского языков соответственно. Поддерживается большое кол-во языков.
Сообщение отредактировал Barba - Четверг, 27.01.2011, 11:33
Откроем button.inc с помощью блокнота и что мы видим. Видим комментарии. Как вы уже догадались комментарии начинаются со знака % В каждом комментарии свой смысл давайте рассмотрим
Button handling (Обработка Шаблона) Содержаться переменные, которые могут использоваться в других скриптах формата inc Button templates (Шаблон кнопки) Тут содержаться основной Стек. Set default button (Кнопка по умолчанию) Кнопка при не наведённом состоянии, т. е. курсор на другой кнопке Make it _not_ the default button (Не кнопка по умолчанию) Кнопка при наведённом состоянии, т. е. курсор на кнопке Set button position (Позиция кнопки) Расположение кнопки Assign action to button (Действий Кнопки.) Действие, совершаемое кнопкой при нажатии Draw button (Прорисовка кнопки) Пиксельный чертеж кнопки в нормальном состоянии Press button (Прорисовка нажатия на кнопку) чертеж кнопки при нажатом состоянии
/button.ok - переменная (может быть использована в других скриптах) 0 – X 0 – y 90 – ширина 25 – Высота txt_ok – Текст False – выбрана ли курсором кнопка 0 – горячие клавиши (можно посмотреть в system.inc) 0 – действие
Всё остальное смотрите в приложении urok.doc или urok.rtf
Где можно взять уроки по программированию gfxboot или @DED-LEGO@
Насчет уроков - не знаю . Сам долго искал хоть какие-нибудь пояснения. Все что есть - это описание языка (файл "Язык скриптов для gfxboot.html" в папке "DOCs"). Остальное пришлось разбирать по исходникам gfxboot (inc-скрипты). Да, еще! Язык PostScript-подобный. Ключевая фраза из этой Wiki-статьи:
Quote
Синтаксис языка использует обратную польскую нотацию, что делает ненужным использование скобок, однако требует некоторой практики для чтения текста программы из-за необходимости держать в голове содержимое стека. Большинство операторов берут операнды со стека и помещают результат вычислений на стек. Литералы (строки и числа) помещают свою копию на стек.
Еще пара слов. Файлы dedxxxx.inc из проекта @DED-LEGO@ - это скрипты, написанные мною. Исправления, сделанные в базовых скриптах помечены комментариями со словом "ded", так что желающие их могут отследить в любом текстовом редакторе и задать вопросы если надо.
gfxboot - составная часть Linux-проектов, а по этой части я слабоват (мягко говоря ). Но, со свой стороны, постараюсь ответить на все вопросы по программированию gfxboot.
@DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Среда, 26.01.2011, 23:06
currentpoint bt.width bt.height window.current .color.bg get setcolor fillrect moveto
bt.default { black black } { window.current .color.bg get dup } ifelse bt.width bt.height drawborder moveto 1 1 rmoveto white black bt.width 2 sub bt.height 2 sub drawborder moveto % 2 2 rmoveto white black bt.width 4 sub bt.height 4 sub drawborder
window.current .color.fg get setcolor moveto bt.x.textofs bt.y.textofs rmoveto bt.text show } def
bt.x 3 add bt.y 3 add moveto bt.width 7 sub bt.height 7 sub savescreen 1 1 rmoveto dup restorescreen free
bt.x 1 add bt.y 1 add moveto black white bt.width 2 sub bt.height 2 sub drawborder % bt.x 2 add bt.y 2 add moveto black white bt.width 4 sub bt.height 4 sub drawborder } def
я бы разобрал button.inc
Добавлено (25.01.2011, 19:18) --------------------------------------------- /button.ok /button.cancel /button.reboot /button.continue как я подумал это переменные которые могут указываться в других inc файлах
Сообщение отредактировал BEGFRAET - Вторник, 25.01.2011, 19:16
Ого! Вы так глубоко копаете! У меня при таком наскоке "черенок" сломался! Я всего этого так и не разобрал. Просто для себя выделил inc-файлы, с работой которых необходимо разобраться. Это system.inc, common.inc и main.inc. Копать начинал с timeout.inc, но в конечном итоге вместо него стал использовать свои модули из ded-LEGO.inc. Остальные inc-и отложил "на потом" и успешно "забыл" про них, т.е. так и не разбирал. Понял только, что они реализуют категории "кнопки", "диалоги", "окна", "панели". Иерархия вроде бы именно такая. Хотя последние две категории может и нужно поменять местами (разбирался, но уже не помню)
Что касается приведенного вами фрагмента. Речь идет о кнопках из "диалогов" (например "ОК", "Cancel") или с "панелей" ("F1", "F2" и все то что Вы хотели отключить) Знак "%", как Вы уже наверняка догадались - знак комментария. Отдельные скрипты отделены строчками
Пишу так подробно, в надежде, что к нам присоединятся и другие желающие. В самом начале указано, что каждый объект кнопка является массивом данных, который содержит следующие параметры. [ x y width height label selected hotkey action ] координаты, размеры, текст на кнопке, состояние, горячая клавиша, действие. Далее описаны несколько кнопок.
(пишу продолжение...)
Добавлено (25.01.2011, 20:01) --------------------------------------------- Теперь посмотрим на первый скрипт. % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % Set default button. % % ( button ) => ( button ) % /button.default { dup 5 true put } def В описании каждого скрипта указано ЧТО ДОЛЖНО НАХОДИТЬСЯ В СТЕКЕ при вызове этого модуля. Здесь написано % ( button ) => ( button ) то есть на входе должен быть объект (массив) кнопка и на выходе тоже будет объект кнопка, но модифицированный. Что значит "на входе должен быть объект (массив) кнопка"? Это значит, что обращение к этому модулю должно выглядить так: button.ok button.default Как будет происходить работа. Мне проще представить это как следующую расшифровку button.ok dup 5 true put Видите, что мы сделали? Описание любого объекта, будь то переменная, массив или скрипт начинается со знака "/", далее идет имя объекта, завершается описание командой "def". Фигурные скобки являются указанием на процедуру, т.е. последовательность команд. (Массивы, как мы видели, задаются перечислением элементов в квадратных скобках.) Поэтому вместо имени процедуры я написал ее содержание. button.ok dup 5 true put Здесь уже нет ссылок на какие-либо процедуры, а фигурируют только команды самого языка. Стиль их описания в вышеуказанном файле такой же. Всегда расписано, что должно быть в стеке перед исполнением команды и что получается в результате. Команда dup дублирует элемент на вершине стека.
Стек - область памяти, но не с произвольным, а с последовательным доступом. Причем доступен в первую очередь тот элемент, который был помещен в стек="помещен на вершину стека" ПОСЛЕДНИМ. Как себе это представить? Помните детские пирамидки, в которых на деревянный штырь насаживались колечки? Я себе стек представляю подобным образом. Помещаем в стек (т.е. нанизываем на штырь) последовательно крсаное, синее, желтое и зеленое кольцо. Что у нас сейчас на вершине стека? Правильно - зеленое кольцо, то которое мы поместил последним, а использоваться оно будет первым.
Добавлено (25.01.2011, 20:30) --------------------------------------------- Получается, что наша запись button.ok dup 5 true put эквивалентна записи button.ok button.ok 5 true put Теперь у нас наверху "пирамидки" два зеленых кольца. Во всей этой цепочке осталась всего одна команда put. Перед ее выполнением в стек помещаются два объекта - число 5 и логическое значение true. Будем считать, что на пирамидку нацепили еще два кольца. По описанию команды put - это команда записи в массив. Для ее работы в стек помещается имя массива, номер элемента массива, который мы меняем и значение, которое нужно поместить. Таким образом, подчеркнутый кусок означает "записать в 5-ый элемент массива button.ok значение true". Нумерация элементов начинается с нуля, следовательно мы меняем статус кнопки "ОК" на true, что, по-видимому, будет интерпретироваться как кнопка "по умолчанию" в каком нибудь диалоговом окне. Ну и , наконец, самое важное. Что происходит со стеком? По описанию команды put она берет из стека три объекта (или элемента, или значения) выполнеят действие и ничего не помещает в стек. То есть мы сняли с пирамидки три кольца, стало быть на пирамидке попрежнему четыре кольца и верхнее - зеленое, т.е. как и было указано в описании % ( button ) => ( button ) мы что-то сделали с кнопкой (изменили ее статус), сохранив при этом указатель на нее. У-ф-ф-a!
@DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Вторник, 25.01.2011, 19:45
Файлы с расширением ".inc"(включение) представляют собой шаблоны (текстовые), написанные на языке типа PHP, созданном специально для веб-программирования. Синтаксис очень напоминает синтаксис языка C и во многом заимствован из таких языков как Java и Perl.
Не согласен! Язык является сильно урезанной версией Postscript-а. Еще раз обращаю Ваше внимание, на способ записи команд описанный в Wiki.
Quote
Синтаксис языка использует обратную польскую нотацию, что делает ненужным использование скобок, однако требует некоторой практики для чтения текста программы из-за необходимости держать в голове содержимое стека. Большинство операторов берут операнды со стека и помещают результат вычислений на стек. Литералы (строки и числа) помещают свою копию на стек.
Пример1. Команда moveto перемещает курсор в заданную точку экрана (система координат начинается в левом верхнем углу). Для того чтобы встать в точку с координатами (75;300) необходимо сначала поместить в стек значения координат, а уж потом дать команду. Можно сказать, что это перемещение графопостроителя с поднятым пером. 75 300 moveto Команда lineto действует аналогично, только рисующее "перо" графопостроителя оставляет след. Например, нарисуем треугольник с вершинами в точках (x1;y1) (x2;y2) (x3;y3)
Code
x1 y1 moveto % встали на первую вершину x2 y2 lineto % прорисовали одну сторону x3 y3 lineto % прорисовали вторую сторону x1 y1 lineto % третья сторона замыкает контур
Аналогично можно нарисовать и прямоугольник, и любой другой многоугольник, но зачастую, прямоугольник, задается левым верхним углом и размерами.
Пример2. Команда rmoveto позволяет сместиться не в абсолютных координатах, а относительно текущей позиции курсора. Таким образом, чтобы от текущей позиции пройти по вершинам прямоугольника со сторонами 75х35 точек можно написать такой код:
Code
75 0 rmoveto % сместились ВПРАВО на 75 точек 0 35 rmoveto % спустились ВНИЗ на 35 точек -75 0 rmoveto % сместились ВЛЕВО на 75 точек 0 -35 rmoveto % поднялись ВВЕРХ на 35 точек
Беда только в том, что команды rlineto нет, и пройти-то мы прошли, а прямоугольник не нарисовали :). Воспользуемся командой currentpoint, которая помещает в стек текущие координаты курсора
Code
currentpoint % запомнили точку СТАРТА x0 y0 75 0 rmoveto % сместились ВПРАВО на 75 точек currentpoint % запомнили следующую x1 y1 0 35 rmoveto % спустились ВНИЗ на 35 точек currentpoint % запомнили следующую x2 y2 -75 0 rmoveto % сместились ВЛЕВО на 75 точек currentpoint % запомнили последнюю x3 y3 0 -35 rmoveto % поднялись ВВЕРХ на 35 точек % %==> теперь мы в исходной точке x0 y0, %==> а в стеке последовательно записано %==> x0 y0 x1 y1 x2 y2 x3 y3 %==> Ура! Можно воспользоваться командой lineto % lineto % нарисовали от текущей x0 y0 до x3 y3 lineto % нарисовали от текущей x3 y3 до x2 y2 lineto % нарисовали от текущей x2 y2 до x1 y1 lineto % нарисовали от текущей x1 y1 до x0 y0
Обратите внимание! По окончании того или иного блока мы должны выбрать ВСЁ ЧТО ПОМЕЩАЛИ В СТЕК! Иначе произойдет накопление и переполнение стека. @DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Четверг, 27.01.2011, 01:59
Пока что у нас все больше теоретические изыскания , а хочется перейти к практическим экспериментам. Поэтому быстро пройдемся по простейшим командам.
1. Команда show выводит на экран значение строковой переменной или константы, которая лежит на вершине стека. Вывод начинается с текущего положения курсора ("пера"). Точнее, прямоугольник, в который помещается текст, своим левым-верхним углом будет находиться в текущей позиции курсора. После вывода текста курсор перемещается в правый-верхний угол этого прямоугольника. Это позволяет использовать несколько команд show подряд.
Code
321 123 moveto % перешли в нужную точку экрана "Hello world!" % поместили в стек строку show % вывели ее на экран
Если мы выводим значение переменной, то она должна содержать текст, иначе получим сообщение об ошибке.
2. Команда setcolor берет из стека число и устанавливает цвет нашего "пера". В стеке, само собой, может быть как переменная, так и число. Цвет удобнее задавать в шестнадцатиричном виде, т.к. при этом каждые две цифры соотвтетствуют одному из цветов триады Red-Green-Blue (красный-зеленый-синий). То есть вот такой-вот 16-ричный вид 0xRRGGBB. Например, 0xFF0000 - чисто красный цвет 0x00FF00 - чисто зеленый 0x0000FF - чисто синий. Уменьшение каждой цветовой составляющей, соответствует затемнению, т.е. 0x880000 тоже синий цвет, но гораздо более темного оттенка.
Code
321 123 moveto % перешли в нужную точку экрана 0xFF0000 setcolor % включили красный "Hello " show % напечатали текст 0xFFFF00 setcolor % включили желтый "word! " show % напечатали текст 0x888888 setcolor % включили серый "It's me :-)" show % напечатали текст
В файле common.inc предопределены некоторые цвета, т.е. к ним можно обращаться "по имени", например red setcolorВнимание! Переходим к практике! Еще раз напомню, что общий вид отдельного скрипта таков: /script.name { % имя и начало скрипта ... % действия } def % конец скрипта и команда "определить" Одиночные присваивания значений имеют такой же вид. Если нет блока операций, а указывается имя-значение-определить, то фигурные скобки не нужны, например: /red 0xff0000 def Важно! Все скобки (и фигурные, и квадратные) должны быть парными. Поэтому для редактирования скриптов ОЧЕНЬ ЖЕЛАТЕЛЬНО использовать текстовые редакторы с подсветкой синтаксиса. В таком случае, став курсором на открывающуюся фигурную скобку в начале скрипта, Вы легко найдете его конец.
Задание: Найдите начало и конец скрипта KeyEvent из common.inc. Чем он примечателен? Это одно из зарезервированных имен и одна из ключевых функций обработки событий. Она вызывается каждый раз при нажатии какой-либо клавиши. В ней анализируется код нажатой клавиши и если он совпадает с кодом одной из "горячих клавиш", то вызывается скрипт для ее обработки. На самом деле все несколько сложнее, но пока нас устроит и такая интерпретация. Посмотрим чем заканчивается этот примечательный скрипт и что нам нужно сделать для включения СВОИХ ДЕЙСТВИЙ по нажатию СВОИХ ГОРЯЧИХ КЛАВИШ. У меня он заканчивается так.
Code
.............................. } if "" -1 0 } def
Т.е. перед выходом из него что-то помещается в стек ("" -1 0), а вот } if - это конец какой-то последней проверки. Вот между этими строчками и вставим наш нехитрый код
Code
.............................. } if
[b]% ------------- % вызов нашего скрипта с именем do.any.script % при нажатии клавиши Del % key keyDel eq { do.any.script } if % % конец нашей вставки % -------------[/b]
"" -1 0 } def
Обращаю Ваше внимание, что не следует писать символы вплотную к скобкам. Обязательно ставьте пробел до и после скобки, чтобы она случайно не превратилась в имя переменной.
@DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Четверг, 27.01.2011, 21:56
Осталось решить вопрос куда поместить свой скрипт.
Настоятельно рекомендую писать свои скрипты в отдельном файле!
Назовите его, скажем, experiments.inc. А чтобы он включился в проект, отредактируйте файл boot.config. Откройте его в текстовом редакторе и после %% include system.inc допишите еще одну строчку %% include experiments.inc
Теперь откройте свой сборник скриптов experiments.inc и повторите какой-нибудь из вышеописанных примеров, но в виде оформленного скрипта с именем do.any.script, потому что именно этот скрипт указан в последнем примере для вызова при нажатии клавиши Del. Например:
Code
/do.any.script {
321 123 moveto % перешли в нужную точку экрана 0xFF0000 setcolor % включили красный "Hello " show % напечатали текст 0xFFFF00 setcolor % включили желтый "word! " show % напечатали текст 0x888888 setcolor % включили серый "It's me :-)" show % напечатали текст
} def
И еще. Как мне кажется, в компиляторе скриптов какой-то глюк, поэтому в самом конце experiments.inc после всех скриптов добавьте пару комментариев, типа % (с) мои самопальные скрипты :-)
@DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Четверг, 27.01.2011, 22:05
Для того чтобы практические занятия получили смысл нам нужно разобраться с элементарными действиями над числами и логическими (булевыми) переменными. Сразу оговорюсь, наверное блоьшинство из нижеизложенных команд, можно применять не только к числам, но и иногда к строковым переменным, к массивам или другим объектам. Но, во-первых, мы с этими объектами еще не знакомы (с некоторыми я так и не познакомился ), а во-вторых, логика их применения сложновата для начального уровня. Тех же, кому данное изложение покажется примитивным и пресным, отсылаю к первоисточнику наших знаний - СПРАВОЧНИКУ gfxboot.
Команда add предназначена для сложения. Все просто, только не забывайте, что она работает над стеком, то есть берет из стека два числа и на их место помещает результат сложения. От перемены мест слагаемых результат, естественно не зависит. 5 7 add Уровень стека понизится на вершине будет лежать результат =12 Следующие примеры дадут одинаковый результат разным способом. 5 7 add 13 1 add add 5 7 add 13 add 1 add 5 7 13 add 1 add add 5 7 13 1 add add add Просмотрим первую строку слева-направо. Первая команда add берет из стека 5 и 7, суммирует и помещает в стек число 12. Получаем цепочку 12 13 1 add add Опять проматриваем слева направо. Команда add берет со стека 13 и 1 помещает на стек 14 12 14 add Дальше - очевидно =26 Повторите рассуждения для трех других примеров и Вы получите тот же самый результат. ВНИМАНИЕ!Одинаковость результата в данном случае обеспечивается арифметикой, а никак не языком. Это все то же школьное правило, что от перемены мест слагаемых сумма не меняется. Замечание: В последнем примере команда add повторилась три раза подряд. Для сокращения подобных записей используется команда repeat. Запись 3 { add } repeat эквивалентна трехкратному суммированию, т.е. add add add. Цепочка кода может быть и бОльшей длины, разумеется. Однако с помощью repeat можно задавать и повторяющиеся цепочки данных. Например, мы уже знаем, что элементы массива перечисляются в квадратных скобках. Если нужно, например, обнулить массив из 100 элементов, то с помощью repeat это делается элементарно. Напомню, что скобки с двух сторон обрамлены пробелами. /my.array [ 100 { 0 } repeat ] def sub - вычитание. Операция на стеке и важен порядок помещения в стек. Сначала в стек помещается уменьшаемое, т.е. то число из которого вычитаем, а потом вычитаемое. 12 7 sub Уровень стека понижается, на вершине будет лежать число 5.
5 7 sub 13 1 sub sub 5 7 sub 13 sub 1 sub 5 7 13 sub 1 sub sub 5 7 13 1 sub sub sub Первый пример даст (5-7)-(13-1)=-14 Второй: ((5-7) -13)-1=-16 Третий: 5-((7-13)-1)=12 Четвертый: 5-(7-(13-1))=10 Обратите внимание, что для указания порядка действий в скрипте нам не пришлось использовать скобки, как при расшифровке. Это одна из особенностей стек-ориентированных языков. Предполагается, что отсутствие скобок повышет оптимизированность, а следовательно и быстродействие программ, написанных с помощью таких языков.
@DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Воскресенье, 30.01.2011, 23:37
mul - умножение. Берем два числа из стека, умножаем, результат кладем на вершину стека. Арифметика нам говорит, что порядок безразличен. 12 7 mul Однако, еще нас учили, что операции умножения и деления имеют бОльший приоритет, чем вычитание и сложение. Но это относится к "скобочным" языкам. В нашем яыке действует правило "Кто раньше, тот и действует!". Вот несколько вариантов... 5 7 sub 13 1 add mul 5 7 sub 13 mul 1 add 5 7 13 mul 1 sub sub 5 7 13 1 mul sub mul ... и их расшифровки. Я преднамеренно взял вышеизложенный пример и только поменял названия опреаций. Смотрите, скобки, регулирующие порядок действий в нашем понимании, остались теми же, т.к. расположение команд в примере сохранилось. Первый пример даст (5-7)х(13+1)=-28 Второй: ((5-7)х13)+1=-25 Третий: 5-((7х13)-1)=-85 Четвертый: 5х(7-(13х1))=-30 div - деление. Однако не простое деление, а целочисленное. Целочисленное деление - это деление с остатком. Остаток при этом отбрасывается не зависимо от его величины, т.е. округления не происходит. Для получения остатка от деления используется другая команда (mod), но о ней позже. 12 7 div 12:7=1 (ост 5). Остаток отбрасываем, а единица идет на вершину стека. Тоже, казалось бы, не так уж и мудрёно. Однако и тут можно наткнуться на "подводные камни". Операции умножения и деления "по школе" - одноуровневые операции и поэтому AxB:C=B:CxA. НО! У нас речь идет о ЦЕЛОЧИСЛЕННОМ ДЕЛЕНИИ, у которого арифметика отличается. C одной стороны три варианта записи... 16 4 div 13 mul 13 16 4 div mul 13 16 mul 4 div ... дают одинаковый результат =52, а точно такой же порядок действий над другими числами дает различающиеся ответы... 17 4 div 13 mul 13 17 4 div mul 13 17 mul 4 div ...первые два дают 52, а третий =55. Ошибка, понятное дело, кроется в отбрасывании остатка. Т.к. последний пример дает более точный результат, то можно было бы для себя выработать правило, что для повышения точности нужно сначала выполнить все действия, кроме деления (если есть выбор, конечно), а уж в последнюю очередь заняться делением, но и тут тоже есть подводный камень! В погоне за точностью можем забыть, что на каждую переменную у нас выделяется только четыре байта, т.е. мы работаем с целыми 32-битными числами со знаком от -2147483648 до 2147483647. Так вот, в погоне за точностью не увлекайтесь умножением, ато "зашкалит" @DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Понедельник, 31.01.2011, 00:09
abs - абсолютная величина числа. Берет с вершины стека число "убирает у него знак" и кладет на вершину стека. Уровень стека не меняется.
max и min - работают одинаково берут с вершины стека два числа, а возвращают одно. В первом случае - то, которое больше, а во втором - меньшее.
mod - остаток от деления. Это та самая операция, которая выделяет остаток при целочисленном делении. Помните наш пример:
Quote
12 7 div 12:7=1 (ост 5). Остаток отбрасываем, а единица идет на вершину стека.
Так вот... 12 7 mod действует иначе 12:7=1 (ост 5) целая часть (это 1) отбрасывается, а на вершину стека идет остаток (это 5).
neg - в отличие от abs не "убирает знак числа", а меняет его на противоположный "+" на "-", а "-" на "+". Казалось бы команда избыточная, т.к. она равносильна умножению на "-1", но neg несколько быстрее. Уровень стека не меняется.
shl и shr - тоже, казалось бы, избыточные команды, но очень нужные для выделения отдельных байтов или даже битов из наших "32-битовых целых со знаком". Буквы "sh" в именовании команд - это сокращение от "shift"=сдвиг. Команды предназначены для побитового сдвига влево (shl) или вправо (shr). Используют два аргумента, т.е. берут из стека два числа. Количество побитовых сдвигов и собственно обрабатываемое число. Результат помещают в стек. Разберем на примерах. 5 3 shl 5 1 shr В обоих случаях обрабатывается число 5, в первом указан побитовый сдвиг влево на три разряда, а во втором вправо на 1 разряд. Для получения результата "ручками", вспомним как 5 записывается в двоичном представлении 5=101b При сдвиге разрядов влево, в свободные разряды справа пишутся нули. 1-й сдвиг <- 1010b=10 2-й сдвиг <- 10100b=20 3-й сдвиг <- 101000b=40 Замечаете, что при однократном сдвиге влево число умножается на 2? Аналогично, при сдвиге на разряд вправо, число делится на два. 1-й сдвиг -> 10b=2 А, поскольку, младший разряд в таком случае просто пропадает, то мы имеем дело с ЦЕЛОЧИСЛЕННЫМ ДЕЛЕНИЕМ на 2. (Но у нас другого-то и нет, да и вообще числа только целые ). Многократный сдвиг соответствует умножению (влево) или делению (вправо) на степень двойки. Не забывайте при этом и про старшие разряды. Помните, что их у нас всего 32. Можно было бы обойтись делением или умножением, но команды shl и shr специализированные и работают быстрее.
@DED-LEGO@ - конструктор для разработчиков GFX-тем ПОСМОТРЕТЬ
Сообщение отредактировал ded2007 - Понедельник, 14.02.2011, 23:31
Что-то на занятиях у нас никакой активности. Похоже, что студенты прогуливают
Всоседней теме был поставлен вопрос "как отключить выход из gfxboot по нажатию клавиши Esc?". Давайте устроим практические занятия и внесем пару корректив в скрипты от gfxboot.
Все нажатия клавиш, судя по описанию языка, обрабатываются скриптом с зарезервированным именем KeyEvent. Поищем его среди inc-файлов от нашего gfxboot. Обычно этот скрипт находится в файле common.inc. Еще было бы неплохо предварительно заглянуть в начало файла system.inc. Там расположены описания некоторых клавиш. Убедимся, что клавише <Esc> соответствует переменная keyEsc. Кроме того, выпишем для себя название какой-нибудь другой клавиши или клавиатурной комбинации, на которую хотелось бы переназначить выход из gfxboot. Ну, скажем, keyCtrlEnd. Идея проста. Открываем common.inc в текстовом редакторе и поиском по тексту находим место упоминания переменной keyEsc, меняем ее имя на keyCtrlEnd и сохраняем файл. Дальше все просто - компилируем тему и проверяем, что на нажатие Esc реакции нет, а вот Ctrl+End вызывает окошко "Выход в текстовый режим". Упс, а в common.inc упоминания о keyEsc нет! Подсказка. Из KeyEvent вызывается какой-то другой скрипт, анализирующий нажатые клавиши. В моем случае есть два вызова:
Code
% some special keys debug.input
% put key through normal input queue window.input
Но там тоже нет обработки keyEsc и есть вызовы других модулей! Придется вызвать кинолога с собакой на поиски keyEsc
Искомая строка оказалась в файле main.inc dup keyEsc eq { exit_popup pop 0 } if меняем ее на dup keyCtrlEnd eq { exit_popup pop 0 } if
Осталось только разобраться как вообще отключить выход. Способ №1. Как Вы заметили, каждая клавиша кодируется 4-байтовым числом. Расклад такой: - биты 0-7 - это ASCII код, - биты 8-15 - это Scan-код, - биты 16-31- это статусные биты клавиатуры. (подробности для любопытных). Так вот, впишите в main.inc вместо найденной переменной keyEsc какую-нибудь "маловероятное" четырехбайтовое число и все. dup 0xf0f0f0f0 eq { exit_popup pop 0 } if
Способ №2. Просто закомментируйте весь блок "if", в котором выполняется сравнение текущего буфера клавиатуры с переменной keyEsc. У меня это выглядит так: %# ded=> # dup keyEsc eq { exit_popup pop 0 } if
Друзья, подскажите пожалуйста, а можно каким-нибудь образом отцентровать строки в меню? Ну чтобы у текста было выравнивание не по левому краю, а по середине?