Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   БК-0010/0011 (http://zx-pk.ru/forumdisplay.php?f=59)
-   -   Оконный интерфейс для БК0011 (http://zx-pk.ru/showthread.php?t=18410)

vinxru 10th March 2012 19:46

Оконный интерфейс для БК0011
 
Тут я буду писать реализованное API

Первая цель - это демо программа в корой будет несколько окон MessageBox. Это окно с изображением, текстом, кнопками Да, Нет. На нажатии на кнопку Да будет запускаться еще одно окно. При нажатии на Нет, окно будет закрываться. Окна можно будет перемещать и изменять их размер. Система должна корректно перерисовывать весь инетрфейс (используя отсечение). Используется черно-белый графический режим.

Вторая цель - это панель пуск. При нажатии на пуск открывается всплывающее меню со списком возможных действий и программ. Так же на панели находятся кнопки окон и объем свободной памяти.

Реализованное API

Память:
MemAlloc(R1 - размер) - Выделяет память. Возвращает R0-указатель.
MemFree(R0 - указатель) - Освобождает память.
ZeroMemory(R0 - указатель, R1 - размер) - Заполняет память нулями.
iFreeMem - Объем свободной памяти (только для чтения)

Глобальные переменные
iRectX, iRectY, iRectX1, iRectY1 - Используется для передачи параметров во многие функции.
DecComRect() - Уменьшить iRect (iRectX++, iRectY++, iRectX1--, iRectY1--).

Окна:
CreateWindow(R0-предок, R1-указатель на WndProc) - Создает окно. Возвращает R0-указатель на объект.
DestroyWindow(R0-окно) - Уничтожает окно.
SendMessage(R0-окно, R1-сообщение ...) - Переключает контекст задачи, сохраняет регистры R0-R3, R5 и запускает функцию WndProc.
Invalidate(R0-окно) - Поставить окно в очередь на перерисовку.
WindowFromPoint(R0,R1) - Какое окно находится в этой точке. Возвращается R2-указатель на объект.
RedrawWindows() - Перерисовать интерфейс (Разослать сообщения WM_PAINT. Вызывается системой автоматически при простое.)
iGraphWindow - Окно выбранное для функций рисования (только чтение)

Курсор мыши:
iCursorImage - Изображение курсора
iCursorX, iCursorY - Положение курсора мыши на экране (только для чтения)
ShowMouse() - Показывает курсор мыши
HideMouse() - Прячет курсор мыши (Восстанавливает изображение под ним).

Рисование (эти функции рисуют в окне. Учитывается, если окно частично закрыто другим окном):
SetPixel(R1,R2-положение) - рисование точки
BitBlt(R1,R2-положение, R3-изображение) - Вывод изображения (с отсечением определенным в iComRect)
DrawText(R1,R2-положение, R3-текст) - Вывод текста шрифтом 8x10 (с отсечением определенным в iComRect)
Rectangle() - Вывод прямоугольника размером iComRect
FillRect() - Вывод закрашенного прямоугольника размером iComRect
InverseMode(R1) - Включить/выключить инверсный режим для DrawText и FillRect.

Драйвер экрана (рисует на экране):
DrvSetPixel(...), DrvBitBlt(...), DrvDrawText(...), DrvFillRect(...).
DrvXorRect(...) - Рисование пунктирного прямоугольника XOR-ом (Для изменения размера и положения окна)

Объекты интерфейса (функции WndProc):
CtlWindow(...) - Рамка и заголовок окна. Логика изменения размера, перемещения.

События окон:
WM_CONSTRUCTOR - Получить кол-во дополнительной памяти в объекте окна
WM_PAINT - Окно необходимо перерисовать
WM_LBUTTONDOWN - Нажатие левой кнопки мыши
WM_LBUTTONUP - Отпускание левой кнопки мыши
WM_LBUTTONDBLCLK - Двойной клик
WM_MOUSEWHEEL - Колесо мыши
WM_RBUTTONDOWN - Нажатие правой кнопки мыши
WM_RBUTTONUP - Отпускание правой кнопки мыши
WM_MOUSEMOVE - Перемещение курсора мыши
WM_CAPTURECHANGED - Окно потеряло монополию над курсором мыши
WM_SETFOCUS, WM_KILLFOCUS - Окно получило/потеряло фокус.
WM_KEYDOWN - Нажатие клавиши клавиатуры (рассылается, только если фокус на окне)
WM_DESTROY - Окно сейчас будет уничтожено
WM_ACTIVATE - Окно стало/перестало быть активным (только для объектов CtlWindow)
WM_CLOSE - Пользователь хочет закрыть окно
WM_ENABLE - Изменение свойства Enabled окна
WM_MOVE - Окно было перемещено
WM_SIZE - Размер окна был изменен
WM_TIMER - Таймер

Объект окна доступен для чтения программисту. Он содержит поля:
Task - Задача, которой принадлежит окно
Parent - Указатель на окно предка
FirstChild - Указатель на первое окно ребенка
LastChild - Последнее окно ребенок
PrevWindow - Предыдущий брат
NextWindow - Следующий брат
Left, Top - Относительные координаты окна
Width, Height - Размер окна
X, Y, X1, Y1 - Координаты окна относительно экрана
WndProc - Обработчик сообщений окна
Style & FW_Intersect - Окно частично закрыто другими окнами
Style & FW_TabStop - Окно может получить фокус (получать сообщения WM_KEYDOWN)
Style & FW_Visible - Окно отображается
Style & FW_Enabled - Окно доступно пользователю
Style & FW_TopMost - Окно всегда сверху

Планируемое API я временно убрал. Там очень много функций.

vinxru 11th March 2012 15:22

1 Attachment(s)
Пока только отрисовывается такая картинка и поверх двигается курсор.

По плану сделать вывод текста. И там есть тормоза. Если выводить текст в координаты по горизонтали не кратные 8, то приходится двигать биты. Поэтому я сделаю так, что положение любого окна или объекта будут кратны 8.

Первый этап работы - это сделать демку, где окна будут перемещаться мышью, их размеры будут изменяться. И будет выполняться функции MessageBoxYN и MessageBoxOk. (И следовательно пару десятков побочных функций).

...

А в идеале хочу рабочий стол с файлами и папками. При щелчке по файлу, будет запускаться соответствующая программа. Если тыкнуть на папку, запустится проводник. (Рабочий стол и проводник - это одна и та же программа). Внизу экрана панель ПУСК и кнопки запущенных программ. Вместо времени - объем свободной памяти. Сворачивание программы, выгружает её из ОЗУ.

При запуске стандартной программы, ОС будет закрываться. Хотя можно попробовать сделать при нажатии на кнпоку СТОП, сохранение такой программы на диск и возврат в ОС. (Как было в DOS Shell)

Из программ пока: блокнот, черно-белый пеинт, сапер, косынка, тетрис, таблица символов, калькулятор, панель управления, часы, простейшая БД, календарь, терминал.

CD-Inc 11th March 2012 19:14

Quote:

Originally Posted by vinxru (Post 478207)
По плану сделать вывод текста. И там есть тормоза. Если выводить текст в координаты по горизонтали не кратные 8, то приходится двигать биты. Поэтому я сделаю так, что положение любого окна или объекта будут кратны 8.

Правильно.
Но со сдвигом (кратным 2) для символов,я бы всё таки заморочился, т.к. можно сделать нормальный пропорциональный (в пределах слова) шрифт в т.ч. для цветного режима, только перед выводом можно делать проверку на смещение/ширину символа если 8/8 тупо пихаем BICB/BISB"ами шрифт/экран, иначе двигаем шрифт в Rx+Ry - выводим BIC/BIS"ами на Rx,(ADR) и Ry,2(ADR)
Если окно не будет отрисовываться заново каждую секунду, то скорости хватит, т.е. тормозни не получится

Quote:

Originally Posted by vinxru (Post 478207)
Первый этап работы - это сделать демку, где окна будут перемещаться мышью, их размеры будут изменяться. И будет выполняться функции MessageBoxYN и MessageBoxOk. (И следовательно пару десятков побочных функций).

...

А в идеале хочу рабочий стол с файлами и папками. При щелчке по файлу, будет запускаться соответствующая программа. Если тыкнуть на папку, запустится проводник. (Рабочий стол и проводник - это одна и та же программа). Внизу экрана панель ПУСК и кнопки запущенных программ. Вместо времени - объем свободной памяти. Сворачивание программы, выгружает её из ОЗУ.

При запуске стандартной программы, ОС будет закрываться. Хотя можно попробовать сделать при нажатии на кнпоку СТОП, сохранение такой программы на диск и возврат в ОС. (Как было в DOS Shell)

Из программ пока: блокнот, черно-белый пеинт, сапер, косынка, тетрис, таблица символов, калькулятор, панель управления, часы, простейшая БД, календарь, терминал.

Хорошая вещь для этого СМК:
+ стандартная железка и для 10тки и для 11
+ не занимает основную память (в т.ч. и сист. стек туда можно писать)
+ если всё заработает можно грузить при начальной загрузке с винта автоматом.

Удачи

vinxru 11th March 2012 19:39

Quote:

Originally Posted by CD-Inc (Post 478312)
Хорошая вещь для этого СМК:
+ стандартная железка и для 10тки и для 11
+ не занимает основную память (в т.ч. и сист. стек туда можно писать)
+ если всё заработает можно грузить при начальной загрузке с винта автоматом.

Удачи

Спаисбо. Я собираюсь купить SMK, но пока я бюджет исчерпал на месяц вперед. Если повезет, то я Кристу 2 на молотке куплю. (У неё разрешение 1024x256.)

dk_spb 11th March 2012 21:14

vinxru, Мда, ценничек Вы задрали - мама не горюй.

vinxru 11th March 2012 21:14

1 Attachment(s)
А кодировку какую использовать?
Покоцанную KOI-8 из БК или 1251 ?

Нашел таблицу символов 8х10 по адресу #0112036. Пока её использую.

vinxru 12th March 2012 01:20

Пишу кстати на своем макро-ассемблере. Уверен, что так будет всем понятнее и проще.

Code:

//----------------------------------------------------------------------------
// Вывод текста R5 в (R0,R1)

DrawText:        R3 = R0;
                // Расчет адреса в видеопамяти
                R1 <<= #6;
                R0 >>= #3 + R1 + #040000;       
                // Расчет адреса перехода
                R3 !&= #0FFF8h;               
                R3b = shlTranslate(R3b);
                do {
                  // Обработка всех символов
                  R1b = (R5b)+;
                  ASM BEQ DrawTextRet;
                  R1 !&= #0FF00h; // Долбанное расширение знака
                  // Особенность знакогенератора БК
                  if(R1>#128) R1 -= #32;
                  // Расчет адреса в знакогенераторе
                  R4 = R1 << #3 + R1 + R1 + #0111576;
                  // Высота символа
                  R2 = #10;
                  // Вывод символа
                  do {
                      R1b = (R4b)+;
                    R1 !&= #0FF00h; // Долбанное расширение знака
                    shl(R3)();
                    (R0b)+ |= R1b;
                    ASM SWAB R1;
                    (R0b) |= R1b;
                    R0 += #63;
                  } while(R2--);
                  R0 -= #639;
                };
DrawTextRet:        return;

//----------------------------------------------------------------------------

shlTranslate:        db 14,12,10,8,6,4,2,0;

//----------------------------------------------------------------------------

shl:                R1 <<= #1; R1 <<= #1; R1 <<= #1; R1 <<= #1;
                R1 <<= #1; R1 <<= #1; R1 <<= #1;
                return;

//----------------------------------------------------------------------------
// Работает примерно в 2 раза быстрее

FastDrawText:        // Расчет адреса в видеопамяти
                R1 <<= #6;
                R0 >>= #3 + R1 + #040000;       
                do {
                  // Обработка всех символов
                  R1b = (R5b)+;
                  ASM BEQ DrawTextRet;
                  R1 !&= #0FF00h; // Долбанное расширение знака, попробую еще CLR+BIS
                  // Особенность знакогенератора БК
                  if(R1>#128) R1 -= #32;
                  R4 = R1 << #3 + R1 + R1 + #0111576;
                  // Вывод символа
                  R2 = #10;
                  do {
                    (R0b) |= (R4b)+;
                    R0 += #64;
                  } while(R2--);
                  R0 -= #639;
                };
                return;

Рисует где то секунду.

http://s019.radikal.ru/i603/1203/19/f04e23ed9bd4.png

---------- Post added at 23:20 ---------- Previous post was at 22:25 ----------

Quote:

Originally Posted by dk_spb (Post 478398)
vinxru, Мда, ценничек Вы задрали - мама не горюй.

Это не я задрал. :) Я бы за 500 рублей с удовольствием купил. БК0011 кстати там то же за 5000 руб лежит :)

vinxru 13th March 2012 11:29

Пока будет 4 функции рисования:

SetPixel(x,y) - рисование точки
FillRect(x,y,x1,y1) - рисование прямоугольников и верт/гор линий.
DrawText(tx,ty,x,y,x1,y1,text) - рисование надписи.
InverseMode(f) - Установка цвета букв и цвета фона для (FillRect и DrawText).
BitBlt(x,y,x1,y1,sourceBitmap,sx,sy) - вывод изображения
FocusRect(x,y,x1,y1) - Пунктирный прямоугольник нарисованный XOR-ом (для изменения размера окна).

Этого хватит почти для всего.

В параметрах x,y,x1,y1 задается прямоугольник за пределами которого рисовать нельзя.

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

Пример работы этой функции с параметрами a=(20,20,250,250), b=(60,60,200,200).
http://s60.radikal.ru/i168/1203/14/760abfec6db9.png

Code:

void intersect(RECT& a, RECT& b) {
  // Не переcекается
  if(b.left > a.right || b.right < a.left || b.top > a.bottom || b.bottom < a.top) { draw(a); return; }

  // Низ не тронут
  if(a.bottom>b.bottom) {
    int t = a.top; a.top = b.bottom+1; draw(a); a.top = t;
    a.bottom = b.bottom;
  }

  // Верх не тронут
  if(a.top<b.top) {
    int t = a.bottom; a.bottom = b.top-1; draw(a); a.bottom = t;
    a.top = b.top;
  }

  // Слева не тронуто
  if(a.left<b.left) {
    int t = a.right; a.right = b.left-1; draw(a); a.right = t;
  }

  // Справа не тронуто
  if(a.right>b.right) {
    a.left = b.right+1; draw(a);
  }
}

Вот эта функция будет выполнена для каждого окна, которое закрывает наше окно.

Mad Killer/PG 13th March 2012 11:46

Клaссно,мнe нрaвится,что это в конeчно будeт ГЮИ или нeчто ОСябeльноe с ядром,комaндeром ?

vinxru 13th March 2012 11:59

Коммандер будет.

Мне проще было бы посадить ГУИ на существующую ОС. Что бы не писать поддержку файловой системы. В общем всё как в Windows 3.0.

Надо глянуть на все ОС для БК.

Но распределение памяти и загрузку программ мне придется делать свою. Каждый выделенный блок памяти будет помечаться, к какой задаче он относится. Когда завершаешь задачу, вся занимаемая ей память (и окна) будут уничтожаться. Так же можно будет вести учет памяти занимаемый каждой задачей.

Памяти у БК совсем не много, поэтому я планирую сделать DLL. Каждая функция системы будет хранится в отдельном файле.

В каждой программе будет заголовок в котором будет указано, какие DLL надо загрузить. Система будет перед загрузкой программы догружать все DLL-ки и корректировать адреса в коде. То есть, получится аналог линкера.

Если не нужен объект CheckBox, то его просто не будет в ОЗУ.

В каждой программе будет две специальные функции AppSwap и AppUnswap. Они должны сохранить в файл все настройки программы, а потом загрузить из файла настройки. Когда не будет хватать памяти, пользователь сможет свернуть программу и программа сохранится на диск с помощью этих функций.

Так что это будет ОС с кооперативной многозадачностью. Но если у вас не поворачивается назвать Windows 3.0 операционной системой, то это будет оболочка :)

Хотелось бы получить вот такую картинку, только с панелью ПУСК:
http://upload.wikimedia.org/wikipedi..._workspace.png

Надеюсь, что получится на 16-48 Кб ОЗУ и тормозном процессоре (относительно 286 25 МГц, который в 30 раз быстрее)


All times are GMT +4. The time now is 02:37.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.