akasei napisał(a):
Implementacja tego GUI, http://forum.osdev.org/download/file.php?id=2787&mode=view
może mi przysporzyć nie lada problemu.
Jedyna trudność to ten efekt cienia pod oknem, ale możesz go na razie nie robić.
akasei napisał(a):
Implementacja tego GUI, http://forum.osdev.org/download/file.php?id=2787&mode=view
może mi przysporzyć nie lada problemu.
Jedyna trudność to ten efekt cienia pod oknem, ale możesz go na razie nie robić.
Azarien napisał(a):
akasei napisał(a):
Implementacja tego GUI, http://forum.osdev.org/download/file.php?id=2787&mode=view
może mi przysporzyć nie lada problemu.Jedyna trudność to ten efekt cienia pod oknem, ale możesz go na razie nie robić.
Tak, cienie (jak i przeźroczystość) to spore obciążenie dla procka.
Przyjąłem taki prosty motyw, szukam teraz znaku X do zamknięcia aplikacji.
@Akasei Zastanawiam się nad poziomem skomplikowania, który będzie bardzo, bardzo szybko rósł. GUI to przecież o wiele bardziej złożona maszyneria niż tryb tekstowy. Podziwiam Twoją wiedzę w zakresie ASM, naprawdę. Niemniej zastanawiam się czy zdarzy się taki moment, że poziom skomplikowania kodu i mechanizmów, które to wszystko obsługują na tak niskim poziomie, będzie wart swojej ceny.
Ciekawe czy zdarzy się chwila kiedy pętla bugów, czyli dajmy na to załatanie czegoś spowoduje x
kolejnych bugów, zmusi Cię do przejścia na coś wyższego poziomu :)
@grzesiek51114: Istnieje szansa, że zablokuje się na
elemencie typu textarea...
@jpacanowski jak będe w domu rzucę kodem do zarządzania oknami, bardzo prosty.
@jpacanowski: Brak tu jeszcze zarządzania elementami interfejsu.
;===============================================================================
; wejście:
; rcx - identyfikator specyfikacji okna
window_show:
; zachowaj oryginalne rejestry
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
; oblicz adres elementu na liście
mov rax, STRUCTURE_X_WINDOW.SIZE
mul rcx
; zamień adres na bezwzględny
mov rsi, qword [list_x_windows]
add rsi, rax
; kontynuuj
jmp .ready
.element:
; zachowaj oryginalne rejestry
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
.ready:
; oblicz pozycję Y okna
mov rax, qword [rsi + STRUCTURE_X_WINDOW.y]
mul qword [static_x_scanline_width]
push rax
; oblicz pozycję X okna
mov rax, qword [rsi + STRUCTURE_X_WINDOW.x]
mul qword [static_x_pixel_size]
add qword [rsp], rax
; zamień adres na bezwzględny
pop rdi
add rdi, qword [static_x_cache_address]
; szerokość okna
mov rbx, qword [rsi + STRUCTURE_X_WINDOW.width]
; oblicz szerokość okna w Bajtach
mov rax, rbx
mul qword [static_x_pixel_size]
; wysokość okna
mov rdx, qword [rsi + STRUCTURE_X_WINDOW.height]
; ustaw wskaźnik na przestrzeń stanu okna
mov rsi, qword [rsi + STRUCTURE_X_WINDOW.address]
.loop:
; kopiuj
mov rcx, rbx
rep movsd
; przesuń wskaźnik na następną linię okna
add rdi, qword [static_x_scanline_width]
sub rdi, rax
; pozostały inne linie okna?
dec rdx
jnz .loop
; przywróć oryginalne rejestry
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
; powrót z procedury
ret
;===============================================================================
; wejście:
; rsi - wskaźnik do specyfikacji okna
window_create:
; zachowaj oryginalne rejestry
push rax
push rcx
push rdx
push rdi
; wylicz rozmiar okna w Bajtach
mov rax, qword [rsi + STRUCTURE_X_WINDOW.width]
mul qword [rsi + STRUCTURE_X_WINDOW.height]
mul qword [static_x_pixel_size]
; zapamiętaj rozmiar w Bajtach
mov qword [rsi + STRUCTURE_X_WINDOW.size], rax
; przelicz na ilość stron
mov rcx, STATIC_MEMORY_PAGE_SIZE
xor rdx, rdx
div rcx
; brak reszty? (rzadkość)
cmp rdx, STATIC_EMPTY
je .no_modulo
; ilość stron zwiększona
inc rax
.no_modulo:
; zarezerwuj odpowiednią ilość pamięci do przechowywania stanu okna
call memory_find
jc .error_no_memory
; zapamiętaj adres przestrzeni stanu okna
mov qword [rsi + STRUCTURE_X_WINDOW.address], rdi
; utwórz "ciało" okna (nagłówek, elementy nagłówka (minimalizuj, zamknij itp.), kolot tła okna)
call window_body
; koniec
jmp .end
.error_no_memory:
; flaga, błąd
stc
.end:
; przywróć oryginalne rejestry
pop rdi
pop rdx
pop rcx
pop rax
; powrót z procedury
ret
;===============================================================================
; wejście:
; rsi - wskaźnik do specyfikacji okna
; rdi - wskaźnik do przestrzeni stanu okna
window_body:
; zachowaj oryginalne rejestry
push rax
push rcx
push rdx
push rdi
push r8
; kolor ramki okna
mov eax, STATIC_X_WINDOW_BACKGROUND_COLOR
; szerokość okna
mov rbx, qword [rsi + STRUCTURE_X_WINDOW.width]
; wysokość nagówka
mov rdx, qword [rsi + STRUCTURE_X_WINDOW.height]
.body:
; szerokość okna
mov rcx, rbx
; koloruj okno
rep stosd
; reszta linii?
dec rdx
jnz .body
; przywróć oryginalne rejestry
pop r8
pop rdi
pop rdx
pop rcx
pop rax
; powrót z procedury
ret
;===============================================================================
window_drag:
; sprawdź status lewego klawisza myszki
bt word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB
jnc .end
; sprawdź status lewego klawisza ALT
cmp byte [semaphore_x_key_alt_left], STATIC_FALSE
je .end
; znajdź właściwości okna, które znajduje się pod pozycją kursora
call window_find
jc .end ; brak specyficznego okna pod wskaźnikiem kursora
; czy okno znajduje się a końcu listy?
cmp bl, STATIC_TRUE
je .on_top
; zachowaj wskaźnik do właściwości okna
push rsi
; przesuń okno (element) z listy na koniec (na wierzch)
call window_insert
; zachowaj nową specyfikację, przywróć starą, usuń stare właściwości okna z listy
xchg rsi, qword [rsp]
call window_remove
mov byte [debug], STATIC_TRUE
; przwróć wskaźnik do właściwości okna
pop rsi
.on_top:
;-----------------------------------------------------------------------
; aktualizuj współrzędne okna względem delty przesunięcia kursora
; oś X
mov rax, qword [variable_x_mouse_x_delta]
; brak przemieszczenia po osi X?
cmp rax, STATIC_EMPTY
je .axis_y
; wartość negatywna?
bt rax, STATIC_QWORD_SIGN_BIT
jnc .axis_x_unsigned
; odwróć notacje
not rax
inc rax ; korekta wartości ujemnej
; przesuń współrzędne okna
add qword [rsi + STRUCTURE_X_WINDOW.x], rax
; sprawdź czy okno znajduje się w przestrzeni ekranu
mov rax, qword [static_x_width]
sub rax, qword [rsi + STRUCTURE_X_WINDOW.width]
cmp qword [rsi + STRUCTURE_X_WINDOW.x], rax
jb .axis_y
; koryguj pozycje okna
mov qword [rsi + STRUCTURE_X_WINDOW.x], rax
; sprawdź oś Y
jmp .axis_y
.axis_x_unsigned:
; przesuń współrzędne okna
sub qword [rsi + STRUCTURE_X_WINDOW.x], rax
jns .axis_y ; wystąpiło przekręcenie licznika?
; okno nie może wyjść poza obszar ekranu, koryguj
mov qword [rsi + STRUCTURE_X_WINDOW.x], STATIC_EMPTY
.axis_y:
; oś Y
mov rax, qword [variable_x_mouse_y_delta]
; brak przemieszczenia po osi Y?
cmp rax, STATIC_EMPTY
je .end
; wartość negatywna?
bt rax, STATIC_QWORD_SIGN_BIT
jnc .axis_y_unsigned
; odwróć notacje
not rax
inc rax ; korekta wartości ujemnej
; przesuń współrzędne okna
add qword [rsi + STRUCTURE_X_WINDOW.y], rax
; sprawdź czy okno znajduje się w przestrzeni ekranu
mov rax, qword [static_x_height]
sub rax, qword [rsi + STRUCTURE_X_WINDOW.height]
cmp qword [rsi + STRUCTURE_X_WINDOW.y], rax
jb .end
; koryguj pozycje okna
mov qword [rsi + STRUCTURE_X_WINDOW.y], rax
; koniec
jmp .end
.axis_y_unsigned:
; przesuń współrzędne okna
sub qword [rsi + STRUCTURE_X_WINDOW.y], rax
jns .end ; wystąpiło przekręcenie licznika?
; okno nie może wyjść poza obszar ekranu, koryguj
mov qword [rsi + STRUCTURE_X_WINDOW.y], STATIC_EMPTY
.end:
; powrót z procedury
ret
;===============================================================================
; wejście:
; r8 - pozycja X kursora
; r9 - pozycja Y kursora
; wyjście:
; Flaga CF jeśli brak elementu
; bl - STATIC_TRUE, jeśli jest to ostatni element listy
; rsi - wskaźnik do elementu
window_find:
; zachowaj oryginalne rejestry
push rax
push rbx
push rcx
push rsi
; znajdź ostatni element na liście
mov rsi, qword [list_x_windows]
; flaga ostatniego elementu listy
mov bl, STATIC_TRUE
; ilość elementów zawartych w liście
xor rcx, rcx
.last:
; element pusty?
cmp qword [rsi + STRUCTURE_X_WINDOW.width], STATIC_EMPTY
je .find
; następny element
inc rcx
add rsi, STRUCTURE_X_WINDOW.SIZE
jmp .last
.find:
; przeszukaj elementy wstecz za pasującym do wzorca (pozycja kursora)
sub rsi, STRUCTURE_X_WINDOW.SIZE
; kursor znajduje się w przestrzeni X,Y?
cmp r8, qword [rsi + STRUCTURE_X_WINDOW.x]
jb .next
cmp r9, qword [rsi + STRUCTURE_X_WINDOW.y]
jb .next
; kursor znajduje się w przestrzeni WIDTH?
mov rax, qword [rsi + STRUCTURE_X_WINDOW.x]
add rax, qword [rsi + STRUCTURE_X_WINDOW.width]
cmp r8, rax
jae .next
; kursor znajduje się w przestrzeni HEIGHT?
mov rax, qword [rsi + STRUCTURE_X_WINDOW.y]
add rax, qword [rsi + STRUCTURE_X_WINDOW.height]
cmp r9, rax
jae .next
; flaga, sukces
clc
; zwróć wynik operacji
mov qword [rsp + STATIC_QWORD_SIZE * 0x02], rbx
mov qword [rsp], rsi
; koniec
jmp .end
.next:
; flaga ostatniego elementu listy
mov bl, STATIC_FALSE
; pozostały inne elementy?
dec rcx
jnz .find
; flaga, błąd
stc
.end:
; przywróć oryginalne rejestry
pop rsi
pop rcx
pop rbx
pop rax
; powrót z procedury
ret
;===============================================================================
; wejście:
; rsi - wskaźnik specyfikacji okna
window_remove:
; zachowaj oryginalne rejestry
push rax
push rcx
push rsi
push rdi
; ustaw wskaźnik docelowy i źródłowy
mov rdi, rsi
add rsi, STRUCTURE_X_WINDOW.SIZE
.loop:
; rozmiar elementu na liście
mov rcx, STRUCTURE_X_WINDOW.SIZE
; element listy pusty?
cmp word [rdi + STRUCTURE_X_WINDOW.width], STATIC_EMPTY
je .end
; przenieś następny element w miejsce aktualnego
rep movsb
; przenieś pozostałe elementy
jmp .loop
.end:
; przywróć oryginalne rejestry
pop rdi
pop rsi
pop rcx
pop rax
; powrót z procedury
ret
;===============================================================================
; wejście:
; rsi - wskaźnik specyfikacji okna
; wyjście:
; rsi - wskaźnik do elementu listy przechowującego specyfikację okna
window_insert:
; zachowaj oryginalne rejestry
push rcx
push rdi
push rsi
; ustaw wskaźnik początku listy okien
mov rdi, qword [list_x_windows]
.loop:
; element listy wolny?
cmp word [rdi + STRUCTURE_X_WINDOW.width], STATIC_EMPTY
je .found
; przesuń wskaźnik na następny element
add rdi, STRUCTURE_X_WINDOW.SIZE
; szukaj dalej
jmp .loop
.found:
; zwróć wskaźnik do elementu listy
mov qword [rsp], rdi
; załaduj właściwości okna do elementu listy
mov rcx, STRUCTURE_X_WINDOW.SIZE
rep movsb
; flaga, sukces
clc
; przywróć oryginalne rejestry
pop rsi
pop rdi
pop rcx
; powrót z procedury
ret
akasei napisał(a):
bt word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB
Ja tu widzę brak abstrakcji sprzętu: kto powiedział że musi być PS2 (nawet jeśli póki co nie obsługujesz innych protokołów).
Azarien napisał(a):
akasei napisał(a):
bt word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB
Ja tu widzę brak abstrakcji sprzętu: kto powiedział że musi być PS2 (nawet jeśli póki co nie obsługujesz innych protokołów).
Spoko napisz mi sterownik do UHCI, EHCI itp, będzie można obsłużyć każde urządzenie po USB, wtedy pisze się abstrakcję.
wtedy pisze się abstrakcję.
Wtedy musisz przeszukać cały kod pod kątem odwołań do PS2, zamiast od razu mieć ładny interfejs.
Patryk27 napisał(a):
wtedy pisze się abstrakcję.
Wtedy musisz przeszukać cały kod pod kątem odwołań do PS2, zamiast od razu mieć ładny interfejs.
Przeszukiwać to za dużo powiedziane :) ale,
jak uznam, że wystarczająco długo siedziałen nad X, może przejdę do pisania obsługi USB. Teraz myszka ogranicza sie tylko do Xów.
Twoje podejście brzmi jak nie będę tworzył VFS, bo póki co obsługuję tylko FAT
;-)
Nie chodzi o żadną obsługę USB, tylko o abstrakcję dostępu do sprzętu.
Patryk27 napisał(a):
Twoje podejście brzmi jak
nie będę tworzył VFS, bo póki co obsługuję tylko FAT
;-)
Nie chodzi o żadną obsługę USB, tylko o abstrakcję dostępu do sprzętu.
Dobra, przedstawię to z innego punktu widzenia. Jeśli nie mam obsługi przynajmniej dwóch urządzeń tego samego typu na różnych protokołach to nie wiem jak mam skonstruować abstrakcję. Proste (przynajmniej dla mnie).
W tym momencie mam "abstrakcję" obsługi myszki, wiem co zrobiła i który klawisz naciśnięto. Nie pytam się jej bezpośredno tylko jądro podaje mi tą informację.
bt word [variable_x_mouse_status], STATIC_PS2_DEVICE_MOUSE_PACKET_BIT_LMB
Ja tu widzę brak abstrakcji sprzętu: kto powiedział że musi być PS2 (nawet jeśli póki co nie obsługujesz innych protokołów).
Spoko napisz mi sterownik do UHCI, EHCI itp, będzie można obsłużyć każde urządzenie po USB, wtedy pisze się abstrakcję.
Nie chodzi o pisanie sterowników. Chodzi o to, że już teraz powinienieś pisać kod z założeniem, że są różnie rodzaje myszy. Nazwa PS2 i szczegóły protokołu powinny się pojawiać tylko w obrębie sterownika myszy PS/2, a nie w kodzie po prostu używającym myszy.
Albo inaczej: okno nie powinno wiedzieć, jakiego rodzaju mysz jest podłączona.
Rozumiem, w sumie mogę tą nazwę zmienić, bo już nie dotyczy PS2 :)
wataha.net nie działa :(
Dobra, muszę przywrócić obsługę GRUBa.
Kompilacja co chwila z inną rozdzielczością jest... nieefektywna ;)
Praca nad tym zajmie mi trochę czasu, ale będzie warto (będziecie mogli dodać sobie wpis do grub.cfg :)
Rozdzielczość pracy systemu będzie można ustalać z poziomu GRUBa.
Teraz już wiem, nie mogę korzystać z trybu multiboot dla jądra:
http://superuser.com/a/919728
The problem was that my kernel is loaded by multiboot <filename> command and linux is loaded (in most cases) by linux <filename> command. Multiboot specification requires that information about preferred video mode is provided in the multiboot header. If that information is not provided, GRUB switches back to the text mode before starting the kernel and completely ignores gfxpayload variable.
Zatem, trzeba jądro przystosować do ELFa, poszukiwania najprostszego nagłówa ELF w trakcie (lub wygenerowanie własnego http://wiki.osdev.org/ELF#Tables).
https://cseweb.ucsd.edu/~ricko/CSE131/teensyELF.htm
Może Ci się przydać :)
mad_penguin napisał(a):
wataha.net nie działa :(
Hagefid napisał(a)]:
Trzeba wyczyscic HSTS w przegladarce i bedzie działać: http://classically.me/blogs/how-clear-hsts-settings-major-browsers
Jaki sens ma używanie jakiegoś "Strict Security" skoro nie potrafimy dotrzymać ograniczeń, jakie ono nakłada?
Azarien napisał(a):
mad_penguin napisał(a):
wataha.net nie działa :(
Hagefid napisał(a)]:
Trzeba wyczyscic HSTS w przegladarce i bedzie działać: http://classically.me/blogs/how-clear-hsts-settings-major-browsers
Jaki sens ma używanie jakiegoś "Strict Security" skoro nie potrafimy dotrzymać ograniczeń, jakie ono nakłada?
Wcześniej strona leżała na serwerze, który wymuszał HSTS. Teraz jest na innym.
Nie obejdę multiboot :|
Jeśli ktoś ma chęć może wykonać prostą aplikację z GUI (MS Windows, Apple Inc.) podmieniającą nw. wartości na własną rozdzielczość w formacie szesnastkowym.
Na systemach z rodziny GNU/Linux jest to o tyle proste:
# rozdzielczość 1280x720
# 1280 => 0x00000500
# 720 => 0x000002D0
$ echo -ne '\x00\x05\x00\x00' | dd conv=notrunc of=kernel bs=4 seek=9
$ echo -ne '\xD0\x02\x00\x00' | dd conv=notrunc of=kernel bs=4 seek=10
Staram się sprawdzić dlaczego Qemu potrafi się zrestartować...
Qemu startuje i przechodzi w stan wstrzmyania.
Uruchamiam GDB, kod systemu przeskakuje do pierwszego BREAK i wykonuję CONTINUE.
Po paru sekundach otrzymuję restart Qemu i raz jeszcze zatrzymuje mi się w moim BREAK.
Ani jednej informacji co się stało... pięknie kurcze, pięknie.
Z dobrych wiadomości :)
Cyjon działa już na VirtualBox :)
Dobra, znalazłem winowajce... Linux ;) (joke)
A dokładnie to Windows > VirtualBox > Linux > Qemu > Cyjon OS taka incepcja źle wpływa na stabilność systemu :)
Qemu się gubi z obsługą myszki co daje Triple-Fault.
Bochs to nie robi różnicy, bo symuluje wszystko.
VirtualBox ma profesjonalne zarządzanie sprzętem + GuestAddons w pierwszej wirtualce, więc to go nie rusza.
Cyjon OS uruchomiony bezpośrednio na Windows + wirtualka, działa stabilnie.
**
Aktualizacja 16/03/2017**, cofam moje słowa, Qemu zwariował.
Jeśli ktoś ma możliwość sprawdzenia dlaczego wirtualka uruchomiła się ponownie:
(link nieaktualny)
(link nieaktualny)
(link nieaktualny)
Poproszę zawartość rejestru RIP przed restartem lub zawartość stosu (z 256 Bajtów).
Niewiele, dekodowanie pliku BMP.
Błąd restartu Qemu zlikwidowany.
Do pobrania:
Horizon Zero Dawn mam już za sobą, mogę się skupić na Cyjonie.
akasei napisał(a):
Nie mam pojęcia jak wykonać przeźroczystość na bazie kanału alfa, więc pomijam jego obsługę
Załóżmy że na piksel nieprzezroczystego tła R1,G1,B1 chcesz nałożyć piksel bitmapy R2,G2,B2,A2 z zachowaniem jego przezroczystości.
Załóżmy też, że wszystkie wartości są 8-bitowe, czyli 0..255.
Kolor wynikowego piksela wynosi (dla każdego kanału RGB tak samo):
·
·
Jeżeli ta sama bitmapa będzie wielokrotnie nakładana, opłaca się pierwszą część operacji wykonać już podczas ładowania bitmapy do pamięci:
·
·
I tak przetworzoną bitmapę (AR2,AG2,AB2,A2) przechowywać. Nazywa się to PRGBA (P od “premultiplied”). Operacja nakładania jest wtedy trochę szybsza:
·
·
Wszystkie wartości oczywiście konwertujemy z 8 bitów na floating-point i odwrotnie. Czy to da się zrobić w całości na typach całkowitych to już zostawiam jako zadanie dla czytelnika ;-)
@Azarien: jest OK :) po prostu do pamięci odłożyłem kolory w kolejności BigEndian, czli kod dobrze napisałem :D
Za to nie wpadłem na początku na pomysł PRGBA, zostosuję. Dzięki.
Nie wytrzymałem do piątku ;) przeźroczystość w pełnej krasie.
@babubabu: proszę :P
@Akasei: zauważyłem na powyższym filmiku, że nie można przesunąć okienka poza obszar pulpitu (tzn. fragmentu okna, nie całego, bo to by sensu nie miało). Uważasz, że to dobry pomysł, czy jeszcze czegoś w kodzie brakuje (co masz zamiar dopisać), że nie jest to obsługiwane?
@furious programming: Właśnie złapałeś mnie na dopisywaniu tego kodu w tym momencie ;)
Nie był priorytetem.
Proszę bardzo jest poza ekran: