Autor Wątek: On-the-fly Screen Compressor  (Przeczytany 7495 razy)

Phonex

  • *****
  • Wiadomości: 1258
  • Miejsce pobytu:
    Warszawa
On-the-fly Screen Compressor
« dnia: 2018.12.24, 15:47:03 »
Przyszło mi do głowy, żeby połączyć plusy zwykłego ładowania screena i skompresowanego screena, czyli rozkompresowywać na bieżąco w trakcie ładowania. Czemu nie wpadłem na ten pomysł kiedyś?
Kompresor stosuje ten sam algorytm co Fast Compressor, tyle że "w biegu" - nie trzeba czekać na zakończenie ładowania. Nie zmienia kolorów ekranu, jak się ustawi czarne na czarnym, to nie będzie widać ładowania, tylko wtedy po co stosować "on-the-fly"? No ale można.
Kto był na Speccy party 2018.2 to widział, pokazywałem jak działa.
Kompresor zgrywa dwa pliki: dekompresor/loader: normalny plik CODE z nagłówkiem i obrazek: bez nagłówka i z krótkim pilotem żeby zaoszczędzić czas.
Oczywiście krótkiego pilota zgrywa tylko na taśmę, do pliku tap/tzx trafia normalny, trzeba sobie samodzielnie zmienić w razie potrzeby.

Używanie LOAD ""CODE: RANDOMIZE USR 40000
Dekompresor/loader ma 194 bajty, ładuje się pod 40000 i nie jest relokowalny. Uruchomienie RANDOMIZE USR 40000 powoduje załadowanie/rozkompresowanie obrazka.
Jeżeli w grze był skompresowany obrazek to prawdopodobnie już jest tam taka sekwencja żeby załadować i rozkompresować obrazek, więc możliwe że nie trzeba nic zmieniać. Jeżeli było zwykłe LOAD ""SCREEN$ to trzeba zamienić na wspomnianą wyżej parę.

Efekt? Wygląda jak normalne ładowanie obrazka, tylko szybciej! :D
Dzieje się to na tyle szybko, że nie widać zmian szybkości w trakcie (czego trochę oczekiwałem, efektu trochę podobnego do zwalniającego licznika w COPY 128 V3).
Co zyskujemy? Obrazek rysuje się od początku ładowania, nie trzeba przez kilkanaście sekund patrzeć w pusty ekran czekając do końca ładowania żeby rozkompresować. A długość jest mniejsza!

Zastosowanie jest oczywiście tylko do taśmy i do plików tap/tzx na emulatorze.
Załączam przykład. Szczegóły wkrótce.
« Ostatnia zmiana: 2018.12.24, 17:33:52 wysłana przez Phonex »

Dalthon

  • ****
  • Wiadomości: 422
  • Miejsce pobytu:
    TriCity
Odp: On-the-fly Screen Compressor
« Odpowiedź #1 dnia: 2018.12.25, 00:22:20 »
Yeah!! ;)
ZX Spectrum +2 Grey | Just Speccy 128 | ZX Spectrum Next | ZX-Uno 2MB |  Murmulator | Amstrad 6128 | MSX2 Philips VG-8235 | Commodore 64 | Commodore +4 | Atari 520 STF | Amiga 1200

KWF

  • *****
  • Wiadomości: 6776
  • Miejsce pobytu:
    trzecia planeta od Słońca
  • "I co ja robię tu, u-u, co Ty tutaj robisz ..."
    • Insta do lasownia
Odp: On-the-fly Screen Compressor
« Odpowiedź #2 dnia: 2018.12.25, 13:34:21 »
Mogę tylko popodziwiać i trzymać kciuki za chęci. Oby tak dalej.
KWF
-----
R Tape loading error 0:1
Moje zabawki: https://github.com/McKlaud76

tooloud

  • *****
  • Wiadomości: 3173
  • Miejsce pobytu:
    Warszawa
  • mydłem go!
Odp: On-the-fly Screen Compressor
« Odpowiedź #3 dnia: 2018.12.25, 15:54:29 »
Bosko, dzięki!
dużo sprzętu mało czasu.

ZX Freeq

  • *****
  • Wiadomości: 1833
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #4 dnia: 2018.12.25, 18:19:38 »
Niesamowite to jest. dzięki.
ZX80|ZX81+16kB+PandAY|ZX 48k/+/128k+/+2/+2A/+3/Vega/Next|QL+QIDE|JS128|Timex 2048+2040|UK2086|FDD3000+3.5''|AY|ZX HD|Divide2k11/2k14|DivMMC/PicoDivSD|BetaDisk 128|Opus|Masakrator FM|If 1/2/Microdrv|Multiface 1|+2A\B SDI-1|SJS 1/2|ZX Printer|TZXDuino|+3 HxC USB|ZXUno|Omni
Z88|A500/600|PC200|Ent128

Phonex

  • *****
  • Wiadomości: 1258
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #5 dnia: 2018.12.26, 12:47:43 »
Mogę tylko popodziwiać i trzymać kciuki za chęci. Oby tak dalej.

No nie wiem, czy będzie jeszcze jedna taka sytuacja. Jednym z powodów było to, że Tygrys zorganizował speccy party w Remoncie, drugim rozmowa z Dalthonem o kompresorach, trzecim Dalthona "wszystkie ręce na pokład" w związku z Remontem. A w książce "Jak blefować doskonale: programowanie" napisali, że co jakiś czas trzeba coś pokazać żeby ludzie uwierzyli że jestem w tym dobry ;D
Nie miałem pomysłu na demo jako demo, więc postanowiłem napisać użytka i do niego demo ;) Niestety nie udało się go wtedy pokazać.

Czwartym powodem powstania programu, był pomysł.
Pierwsze przemyślenia sugerowały, że rzecz jest niewykonalna. Nie było szans żeby wyrobić się czasowo. Wydawało mi się że jest to jeszcze trudniejsze niż napisanie np. kopiera z kompresją, bo tam jest tak: w czasie ładowania kopier liczy powtarzające się bajty i wynik wpisuje do pamięci (trzy wpisy: znacznik, licznik, bajt), w czasie zgrywania odczytuje ilość (do trzech odczytów z pamięci) a potem wysyła ileś bajtów na taśmę. A tu trzeba odczytać z taśmy jeden do trzech bajtów a potem z tego wykonać 1 do 128 wpisów do pamięci PRZED załadowaniem następnego bajta z taśmy!
To nie mogło się udać.
Aż wpadłem na pomysł, że przecież nie trzeba zakończyć PRZED załadowaniem następnego bajta - można ładować jak zawsze: skompresowany obrazek jak zwykle ładuje się pod 40000, a drugi proces sprawdza sobie czy są nowe bajty i je obrabia. I ponieważ jest jednak więcej nieskompresowanych niż skompresowanych bajtów, to spokojnie można na luzie wpisywać 1 może 2 powtarzające się bajty na raz! Do końca pliku się wyrówna.
To z kolei groziło tym, że jeśli skompresowane bajty będą pod koniec pliku (a często będą - na końcu są atrybuty) - program nie zdąży ich rozkompresować przed zakończeniem ładowania.
Zacząłem już nawet kombinować na ile bajtów przed końcem obrazka zaprzestać kompresji, aż wpadłem na następny pomysł - przecież nie musi skończyć przed zakończeniem ładowania! Po zakończeniu, dzięki temu że to niezależny proces, można wielokrotnie wywoływać dekompresję aż nie zasygnalizuje że już wszystkie bajty zrobione. Bez ładowania uwinie się dosłownie w mgnieniu oka i nawet nie będzie widać.
Żeby nawiązać do Fast Compressora (i może z lenistwa) nie zmieniałem interfejsu programu, dorobiłem tylko pulsującą nazwę, żeby go wyróżnić.

Ach! Teraz pisząc o tym, zrozumiałem dlaczego nie ma oczekiwanego przeze mnie efektu zmian szybkości w trakcie ;) Tego można by oczekiwać po tej pierwotnej "niewykonalnej" wersji.

trojacek

  • *****
  • Wiadomości: 6795
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #6 dnia: 2018.12.26, 13:24:49 »
Ahaaaaaa...! ;)
To teraz wszystko jasne :)


Phonex

  • *****
  • Wiadomości: 1258
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #7 dnia: 2023.04.10, 16:44:34 »
Nagle okazało się, że to już prawie pięc lat! To przez tą epidemię chyba...
Pora na upgrade.
Już wtedy, jak pisałem, wiadomo było że do napisania jest jeszcze jeden - oparty na moim Top Screen Compressor (ups, nie wysłałem go do Archiwum, chyba nie mogłem go kiedyś znaleźć...).
Top - jak nazwa sugeruje - kompresuje lepiej. Lepiej, bo nie analizuje po adresach, tylko kolumnami. A po drugie - ma dwa "najpopularniejsze bajty", które przy kompresji koduje na dwóch bajtach (zamiast trzech), a nie jeden jak "Fast". Pierwszym bajtem jest oczywiście zero, drugi sobie wybiera.
Używa do tego dwóch bitów licznika bajtów. W związku z tym licznik liczy tylko do 63, chociaż potrafi też zakodować 256 zer. Ale chyba się opłaca, bo obrazki kompresowane tym są prawie zawsze krótsze niż "Fastem".

Odłożyłem to na później, bo obliczanie adresu następnego bajta jest skomplikowane - już wyświetlanie z pamięci trwa chyba z pięć razy dłużej.
Ale po pięciu latach już nie ma co zwlekać i jak widać da się :D
Ten "stary" wpisuje dwa powtarzające się bajty przy jednym wywołaniu procedury, teraz dało się tylko jeden, a zamiast INC HL jest podprogram, który sam zajmuje jedno, a czasem aż dwa wywołania. Czyli w czasie jednego bajta z taśmy dostajemy czasem tylko 5 i ćwierć bajta obrazka, a nie 32!
Efekt? Nawet na takim dość pustym obrazku, wyświetlanie może być opóźnione względem ładowania o kilkadziesiąt bajtów. Przy uważnej obserwacji, widać że np. atrybuty są wyświetlane później niż je słychać z taśmy (o ~30 bajtów, czyli ~0,15 sekundy).

Na razie tylko loader, w zasadzie demo loadera, bo stałe czasowe jeszcze nie są przeliczone (w emulatorze działa).
Finalnie będzie nowy kompresor - w wersji ambitnej z wbudowanymi obydwoma sposobami kompresji i możliwością wyboru "najkrótszy(auto)/kolumnami/adresami" - co z kolei było w planie od zawsze czyli od 1990! Myślę że wyrobię się do pełnej 5 rocznicy (grudzień) ;)

Phonex

  • *****
  • Wiadomości: 1258
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #8 dnia: 2023.07.22, 15:41:45 »
A może zrobić pokazywanie od razu z atrybutami?
Bo patrzę na to ładowanie i nie podoba mi się. Tak wygląda dekompresja z pamięci, ale wtedy atrybuty pokazują się po sekundzie... Przy ładowaniu z dekompresją "po pamięci" też atrybuty są później, ale to niewiele odstaje od klasycznego sposobu ładowania, do którego przywykliśmy.
A skoro i tak trzeba przeliczać adresy, i wiem już jak upchnąć w czasie ładowania więcej operacji niż wydawało się możliwe, to może uda się i z kolorami od razu?
Wyglądałoby mniej więcej tak - tylko bez tych artefaktów na atrybutach na początku - to tylko demo, po prostu przestawiłem atrybuty na początek.

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4532
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: On-the-fly Screen Compressor
« Odpowiedź #9 dnia: 2023.07.24, 20:51:02 »
Zawsze dane mogą zawierać adres pamięci dla pixeli i kolorów. Wtedy wprawdzie blok danych będzie trochę dłuższy, ale osiągniesz to co chcesz.

Dalthon

  • ****
  • Wiadomości: 422
  • Miejsce pobytu:
    TriCity
Odp: On-the-fly Screen Compressor
« Odpowiedź #10 dnia: 2023.07.24, 21:02:44 »
Albo dawać kolor atrybutu, 8 bajtów danych wypełniające ten 8*8 i następny atrybut, 8 bajtów... i tak 768 razy ;)
ZX Spectrum +2 Grey | Just Speccy 128 | ZX Spectrum Next | ZX-Uno 2MB |  Murmulator | Amstrad 6128 | MSX2 Philips VG-8235 | Commodore 64 | Commodore +4 | Atari 520 STF | Amiga 1200

Phonex

  • *****
  • Wiadomości: 1258
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #11 dnia: 2023.07.25, 08:36:33 »
Zawsze dane mogą zawierać adres pamięci dla pixeli i kolorów. Wtedy wprawdzie blok danych będzie trochę dłuższy, ale osiągniesz to co chcesz.
Nie warto. To jest dobre jak chce się zrobić fikuśną kolejność pokazywania obrazka, ale bardzo wydłuża blok. A tu będzie zawsze tak samo: kolumnami od lewej.

Albo dawać kolor atrybutu, 8 bajtów danych wypełniające ten 8*8 i następny atrybut, 8 bajtów... i tak 768 razy ;)
Właśnie tak.
Tylko wolę najpierw pixele, a potem kolor, bo jak się zrobi przed ładowaniem INK = PAPER, to będzie się pojawiał od razu cały kwadrat. Będzie wybór :)
« Ostatnia zmiana: 2023.07.25, 08:57:53 wysłana przez Phonex »

Phonex

  • *****
  • Wiadomości: 1258
  • Miejsce pobytu:
    Warszawa
Odp: On-the-fly Screen Compressor
« Odpowiedź #12 dnia: 2023.08.20, 21:16:30 »
Zrobione.
Nawet łatwo poszło - w sensie kodowanie, bo oczywiście znalezienie sposobu znowu wymagało zalogowania się do "tego-jeszcze-nie-grali.com".
Ale po kolei: najprostszy sposób ładowania razem z kolorami pokazałem poprzednio. Naiwnie myślałem, że przestawienie atrybutów na początek załatwi sprawę przynajmniej w większości obrazków. No bo jak jest jednolite czarne tło, to bez pikseli całość będzie czarna, prawda?
Nieprawda. Przez małą rozdzielczość kolorów w Spectrum, obrazki wymagają kombinowania z INVERSE - część treści obrazka jest zrobiona inkiem, część pejperem. W załączniku jest HEAD-atr - to same atrybuty obrazka z Head Over Heels (bez pikseli czyli widać sam PAPER).
Pomysł upadł - wykorzystałem go do zrobienia dema tego, co chcę osiągnąć.
Następny pomysł: przygotować plik tak, żeby atrybuty były co 8 bajtów pikseli. Odpada od razu, bo przecież wszystko jest skompresowane i nie sposób przewidzieć ile bajtów pikseli będzie w jednym rekordzie. Można by pokazać najpierw x bajtów pikseli, a potem x/8 bajtów koloru. Wyglądałoby trochę amatorsko. Chociaż teraz pomyślałem, że może spróbuję w wolnej chwili... ;)
Na szczęście pomysł pierwszy - żeby przestawić atrybuty na początek - naprowadził mnie na rozwiązanie: tak, atrybuty ładują się na początku, ale rozkompresowują nie na ekran tylko wyżej. A potem przy dekompresji/pokazywaniu pikseli, w momencie obliczania kolejnego adresu, gdy po 8 liniach jest potrzebna poprawka przenosząca do następnej linii znakowej, pokazywany jest kolor. Potrzebne są tylko trywialne obliczenia adresu atrybutów z adresu pikseli. Procedura ma 9 bajtów - wreszcie natknąłem się na tą zaletę, która stała za taką akrobatyczną organizacją ekranu - łatwość obliczenia adresu atrybutów! Bo do tej pory napotykałem tylko trudności wydłużające obliczenia. Zorganizowanie kopiowania kolejnych bajtów z pamięci na ekran, to pestka. I nawet uruchomiło się od pierwszej próby :D
W związku z tym program używa teraz również max.768 bajtów od adresu 49152 (16384+32768 dla łatwego adresowania). Wrócił pusty ekran - ale tylko na kilka sekund (średnio 2-3, max.4) kiedy nic nie widać, dopiero potem pokazuje się obrazek. Bardzo ładnie się pokazuje - teraz mi się podoba 8)
Loader/dekompresor jest teraz trochę dłuższy: ma 256 bajtów, czyli jest o 62 dłuższy. To i tak świetny wynik, bo gdyby zachować różnicę długości wersji dekompresujących z pamięci - powinno wyjść 284.

Atrybuty ładują się po pikselach, więc są dwa sposoby wyświetlania: niewidoczny (INK = PAPER w loaderze) gdy piksele są niewidoczne i cały kwadrat pokazuje się wtedy gdy wchodzi kolor i widoczny (INK <> PAPER) gdy piksele widać cały czas. Z tym że to jest szybkie i niespecjalnie widać konkretne piksele, bardziej powstaje efekt kursora.
Mamy też drugi wybór: czy ładować jak zwykle na czarnym tle, czy na białym - tu efekt jest bardziej "dramatyczny", bo zmienia się i tło i treść.

I wreszcie!
Widać zmiany szybkości w trakcie ładowania! :D Jak ładują się puste pola (np. w Vulcan).
Jeszcze szczegół techniczny: ostatnia kolumna Vulcana i dwa kwadraty przedostatniej pokazywane są "offline", a dla Head - 10 ostatnich kwadratów.

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4532
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: On-the-fly Screen Compressor
« Odpowiedź #13 dnia: 2023.08.22, 08:03:14 »
Niezła magia! Super to wyszło ;)

A z pamięcią ekranu ZX to, jak na pierwszy rzut oka, nie wygląda to źle, ot, jedynie trzeba zrozumieć jak to działa, i jak z tego skorzystać (w tym wykorzystując właściwości Z80)