github publish

This commit is contained in:
Ondrej Novak 2025-01-24 18:27:22 +01:00
commit 506e23bf32
542 changed files with 120675 additions and 0 deletions

318
VIDEO/ANIPACK.ASM Normal file
View file

@ -0,0 +1,318 @@
.model small
.386
;16 bit line (de)comprimator
;
DGROUP group _DATA
extern _anim_line_len:dword
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
save_line1 macro reg1,reg2
shr reg1,8
rcr reg2,1
shr reg1,8
rcr reg2,1
shr reg1,8
rcr reg2,1
shr reg1,8
rcr reg2,1
endm
save_linex macro reg1,reg2,rols
shrd reg2,reg1,rols
shr reg1,8
shrd reg2,reg1,rols
shr reg1,8
shrd reg2,reg1,rols
shr reg1,8
shrd reg2,reg1,rols
endm
public save_1bit_ ;ESI source
;EDI target
;vraci EDI ukazatel na konce;
save_1bit_:
mov cl,8
s1b1: lodsd
save_linex eax,ebx,1
dec cl
jnz s1b1
mov eax,ebx
stosd
mov cl,8
s1b2: lodsd
save_linex eax,ebx,1
dec cl
jnz s1b2
mov eax,ebx
stosd
ret
public save_2bit_
save_2bit_:
mov ch,4
c2b11: mov cl,4
c2b12: lodsd
save_linex eax,ebx,2
dec cl
jnz c2b12
mov eax,ebx
stosd
dec ch
jnz c2b11
ret
public save_3bit_
save_3bit_:
mov ch,8
c3b11: mov cl,2
c3b12: lodsd
save_linex eax,ebx,3
dec cl
jnz c3b12
mov eax,ebx
shr eax,8
stosd
dec edi
dec ch
jnz c3b11
ret
public save_4bit_
save_4bit_:
mov ch,8
c4b11: mov cl,2
c4b12: lodsd
save_linex eax,ebx,4
dec cl
jnz c4b12
mov eax,ebx
stosd
dec ch
jnz c4b11
ret
public load_1bit_ ;ESI - Source
;EDI - Target
;EBX - Palette
;anim_line_len - delka radky
load_1bit_ :
mov ch,8
l1b1: mov dl,[esi]
inc esi
mov cl,8
l1b2: movzx eax,dl
and eax,1
mov eax,[ebx+eax*2]
test eax,8000h
jnz short l1b1s
mov [edi],ax
l1b1s: add edi,2
shr dl,1
dec cl
jnz l1b2
mov eax,_anim_line_len
sub eax,16
add edi,eax
dec ch
jnz l1b1
ret
public load_2bit_ ;ESI - Source
;EDI - Target
;EBX - Palette
;anim_line_len - delka radky
load_2bit_:
mov ch,8
l2b1: mov dx,[esi]
add esi,2
mov cl,8
l2b2: mov eax,edx
and eax,3
mov eax,[ebx+eax*2]
test eax,8000h
jnz short l2b1s
mov [edi],ax
l2b1s: add edi,2
shr edx,2
dec cl
jnz l2b2
mov eax,_anim_line_len
sub eax,16
add edi,eax
dec ch
jnz l2b1
ret
public load_3bit_ ;ESI - Source
;EDI - Target
;EBX - Palette
;anim_line_len - delka radky
load_3bit_:
mov ch,8
l3b1: mov edx,[esi]
add esi,3
mov cl,8
l3b2: mov eax,edx
and eax,7
mov eax,[ebx+eax*2]
test eax,8000h
jnz short l3b1s
mov [edi],ax
l3b1s: add edi,2
shr edx,3
dec cl
jnz l3b2
mov eax,_anim_line_len
sub eax,16
add edi,eax
dec ch
jnz l3b1
ret
public load_4bit_ ;ESI - Source
;EDI - Target
;EBX - Palette
;anim_line_len - delka radky
load_4bit_:
mov ch,8
l4b1: mov edx,[esi]
add esi,4
mov cl,8
l4b2: mov eax,edx
and eax,15
mov eax,[ebx+eax*2]
test eax,8000h
jnz short l4b1s
mov [edi],ax
l4b1s: add edi,2
shr edx,4
dec cl
jnz l4b2
mov eax,_anim_line_len
sub eax,16
add edi,eax
dec ch
jnz l4b1
ret
public load_8bit_ ;ESI - Source
;EDI - Target
;EBX - Palette
;anim_line_len - delka radky
load_8bit_:
mov ch,8
l8b1: mov cl,8
l8b2: lodsb
movzx eax,al
mov eax,[ebx+eax*2]
test eax,8000h
jnz short l8b1s
mov [edi],ax
l8b1s: add edi,2
dec cl
jnz l8b2
mov eax,_anim_line_len
sub eax,16
add edi,eax
dec ch
jnz l8b1
ret
public load_0bit_ ;EDI - Target
;EBX - Palette
;anim_line_len - delka radky
load_0bit_:
movzx eax,word ptr[ebx]
test eax,8000h
jnz l0b1s
mov ebx,eax
shl ebx,16
or eax,ebx
mov ch,8
l0b1: mov cl,4
l0b2: stosd
dec cl
jnz l0b2
mov edx,_anim_line_len
sub edx,16
add edi,edx
dec ch
jnz l0b1
l0b1s: ret
public display_interlaced_fused_lfb_
;ESI buffer1
;EBX buffer2
;EDI screen
;vezme buffer 1 a sfuzuje s bufferem 2, predtim ovsem prepise buffer2 bufferem 1
;pracuje s lfb
display_interlaced_fused_lfb_:
mov ecx,180
dif_lp1:push ecx
mov ecx,320
dif_lp2:lodsd
mov edx,eax
xchg edx,[ebx]
and eax,7bde7bdeh
and edx,7bde7bdeh
add eax,edx
shr eax,1
stosd
add ebx,4
dec ecx
jnz dif_lp2
pop ecx
add edi,1280
dec ecx
jnz dif_lp1
ret
extern mapvesaadr_:near
public display_interlaced_fused_bank_
;ESI buffer1
;EBX buffer2
;EDI screen
;vezme buffer 1 a sfuzuje s bufferem 2, predtim ovsem prepise buffer2 bufferem 1
;pracuje s lfb
display_interlaced_fused_bank_:
mov ecx,180
difblp1:push ecx
push edi
call mapvesaadr_
mov ecx,320
difblp2:lodsd
mov edx,eax
xchg edx,[ebx]
and eax,7bde7bdeh
and edx,7bde7bdeh
add eax,edx
shr eax,1
stosd
add ebx,4
dec ecx
jnz difblp2
pop edi
pop ecx
add edi,4096
dec ecx
jnz difblp1
ret
_TEXT ends
end

39
VIDEO/ANIPACK.H Normal file
View file

@ -0,0 +1,39 @@
#ifndef __ANIPACK_H
#define __ANIPACK_H
int anim_line_len=1280;
void load_0bit(void *target,void *palette);
void *load_1bit(void *source,void *target,void *palette);
void *load_2bit(void *source,void *target,void *palette);
void *load_3bit(void *source,void *target,void *palette);
void *load_4bit(void *source,void *target,void *palette);
void *load_8bit(void *source,void *target,void *palette);
#pragma aux load_0bit parm [EDI][EBX] modify [EAX ECX EDX]
#pragma aux load_1bit parm [ESI][EDI][EBX] modify [EAX ECX EDX] value [esi]
#pragma aux load_2bit parm [ESI][EDI][EBX] modify [EAX ECX EDX] value [esi]
#pragma aux load_3bit parm [ESI][EDI][EBX] modify [EAX ECX EDX] value [esi]
#pragma aux load_4bit parm [ESI][EDI][EBX] modify [EAX ECX EDX] value [esi]
#pragma aux load_8bit parm [ESI][EDI][EBX] modify [EAX ECX] value [esi]
void *save_1bit(void *source,void *target);
#pragma aux save_1bit parm[esi][edi] modify [eax ebx] value[edi];
void *save_2bit(void *source,void *target);
#pragma aux save_2bit parm[esi][edi] modify [eax ebx] value[edi];
void *save_3bit(void *source,void *target);
#pragma aux save_3bit parm[esi][edi] modify [eax ebx] value[edi];
void *save_4bit(void *source,void *target);
#pragma aux save_4bit parm[esi][edi] modify [eax ebx] value[edi];
void display_interlaced_fused_lfb(void *buff1,void *buff2,void *lfb);
#pragma aux display_interlaced_fused_lfb parm [esi][ebx][edi]modify [ecx edx eax]
void display_interlaced_fused_bank(void *buff1,void *buff2,void *scr);
#pragma aux display_interlaced_fused_bank parm [esi][ebx][edi]modify [ecx edx eax]
#endif

342
VIDEO/BITLINE.ASM Normal file
View file

@ -0,0 +1,342 @@
.model small
.386
;16 bit line (de)comprimator
;
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
cwrite macro REG,BIT ;zapise al do [di] pouze BIT bitu ze zadu
local cwrit2
shl edx,BIT ;posun EDX o pripraveny pocet bitu
and REG,0ffh shr (8-BIT) ;odmaskuj pripadne bity v REG
or dl,REG ;pridej REG do dl
add ch,BIT ;pripocti pridany pocet bitu
cmp ch,8 ;jestli to preteklo
jc cwrit2 ;ne, vse je OK
sub ch,8 ;ano pak odecti 8 bitu
mov cl,8 ;cl=8-ch;
sub cl,ch ;
shl edx,cl ;tj kolik zbejva posunout.
mov [edi],dh ;zapis osmice
shr dl,cl ;vrat dl do puvodniho stavu
inc edi ;dalsi adresa
cwrit2:
endm
cwrit8 macro REG ;zapise 8 bitu do [EDI]
shl edx,8 ;posun 8 bitu
or dl,REG ;sfuzuj
mov cl,8 ;kolik urcite preteklo
sub cl,ch ;a o kolik teda posunout
shl edx,cl ;posun na dorovnani na bajt
mov [edi],dh ;zapis bajt
shr dl,cl ;spodek vrat do puvodniho stavu.
inc edi ;dalsi adresa
endm
write_ax: ;zapisuje AX do [edi] v komprimovanem tvaru
;hodnoty
; 0 ... 000
; 1 ... 001
; 2 ... 010
; 3 ... 011
; 4 ... 100
; 5 ... 101
; 6 ... 110
; 7 ... 11100000
; 8 ... 11100001
; 9 ... 11100010
;10 ...
;...
;37 ... 11111110
;38 ... 1111111100000000
;39 ... 1111111100000001
;
;291 .. 1111111111111101
;292 .. 1111111111111110
;>293 .. 1111111111111111 Lo Hi
cmp eax,293 ;eax>293 (7+31+255)
jnc wr_16 ;zapis 16 bitove hodnoty
cmp al,38 ;eax>38 (7+31)
jnc wr_8 ;zapis 8 bitove hodnoty
cmp al,7 ;eax>7
jnc wr_5 ;zapis 5 bitove hodnoty
cwrite al,3 ;pro cisla eax<7 (0..6) staci 3 bity
ret ;konec
wr_16: sub eax,293 ;odecti to co je zname
mov cl,0ffh ;zapis dvou hodnot 255 jako znacka ze nasleduje
cwrit8 cl ;16 bitova hodnota
mov cl,0ffh
cwrit8 cl
cwrit8 al ;zapis nizsi
mov al,ah
cwrit8 ah ;zapis vyssi
ret
wr_5: sub al,7 ;odecti co zname
or al,0E0h ;tri bity na 1 znaci 5 bitovou hodnotu
cwrit8 al ;zapis to
ret
wr_8: sub al,38 ;odecti to co je uz zname.
mov cl,0ffh ;zapis jedne hodnoty 255 znaci 8 bitovou hodnotu
cwrit8 cl ;zapis ji
cwrit8 al ;zapis al
ret
;vsechny mody -
; vstup: ESI - data
; EDI - buffer
; ECX - delka dat (max 65535)
; EBX - bitova rovina (bit na pozici roviny = 1)
flush macro
local fjmp
shr ecx,16
or ch,ch
jz fjmp
mov eax,7
call write_ax
fjmp:
endm
public cmode0_
cmode0_: ;komprimuje pro mod 11110000 (uvazuji se retezce 00001 nebo 11110 pricemz
; 0000111110 se pocita vcetne rozdilu (
; \---/\---/
; 4 4 tj 100100
push ebp
xor edx,edx
xor ebp,ebp
xor eax,eax
cmode0b: lodsw
and ax,bx
cmp ax,bp
jnz cmode0a
add eax,10000h
dec cx
jnz cmode0b
shr eax,16
shr ecx,16
call write_ax
flush
pop ebp
ret
cmode0a: xor ebp,ebx
shr eax,16
rol ecx,16
call write_ax
rol ecx,16
dec cx
jnz cmode0b
flush
pop ebp
ret
public cmode1_
cmode1_: ;komprimuje pro mod 00010001
;komprimuje se vcetne jednicky tj
;
;000100001
;\--/\---/
; 3 4 tj 011100
xor edx,edx
xor eax,eax
cmode1b: lodsw
and ax,bx
jnz cmode1a
add eax,10000h
dec cx
jnz cmode1b
shr eax,16
shr ecx,16
call write_ax
flush
ret
cmode1a: shr eax,16
rol ecx,16
call write_ax
rol ecx,16
dec cx
jnz cmode1b
flush
ret
public cmode2_
cmode2_: ;komprimuje pro mod 11101110
;komprimuje se vcetne 0 tj
;
;111101011110111110
;\---/\/\---/\----/
; 4 1 4 4 tj 100001100100
xor edx,edx
xor eax,eax
cmode2b: lodsw
and ax,bx
jz cmode2a
add eax,10000h
dec cx
jnz cmode2b
shr eax,16
shr ecx,16
call write_ax
flush
ret
cmode2a: shr eax,16
rol ecx,16
call write_ax
rol ecx,16
dec cx
jnz cmode2b
flush
ret
public cmode3_
cmode3_: ;kopiruje rovinu
mov edx,8 ;8 bitu
cmode3b: lodsw ;cti slovo
and ax,bx ;kontroluj rovinu
cmp ax,bx ;nastav carry podle vysledku
cmc ;ale spravne
rcl dh,1 ;soupni ho do dh
dec dl ;dalsi pozice
jnz cmode3a ;kdyz to neni vse pokracuj
mov [edi],dl ;je to vse
inc edi ;dalsi bajt
mov edx,8 ;dalsich 8 bitu
cmode3a: dec ecx ;dalsi slovo
jnz cmode3b ;dokud to neni vse.
cmp dl,8
jz cmode3c
mov cl,dl
shl dh,cl
mov [edi],dh
inc edi
cmode3c: ret
; DEKOMPRIMACE
cread macro REG,BIT
local crd1
mov cl,BIT
cmp ch,cl ;zjisti zda pocet zbylych bitu
jnc crd1 ;neni nahodou min nez potrebnych
mov cl,ch ;ano, tj posun ty zbyle do dh
shl edx,cl
mov dl,[esi] ;do dl vloz dalsi bajt
inc esi ;a zvys adresu
sub cl,BIT ;odecti pocet pozadovanych bitu
mov ch,8 ;to je aktualizovana hodnota noveho ch
neg cl ;v cl je nyni mnozstvi chybejicich bitu
crd1: shl edx,cl ;prisun je do dh
sub ch,cl
mov REG,dh ;vem je do REG
and REG,0xff shr (8-BIT) ;odmaskuj horejsek
endm
;vsechny mody -
; vstup: ESI - data
; EDI - vysledek
; ECX - delka dat (max 65535)
; EBX - bitova rovina (bit na pozici roviny = 1)
cread_ax macro
local crd_ok
rol ecx,16 ;nejdriv schovej cx v horni pulce
xor eax,eax ;vynuluj eax
cread al,3 ;nacti 3 bity
cmp al,7 ;pokud to da hodnotu 7 pak pokracuj
jnz crd_ok ;jinak jsem hotov
cread al,5 ;nacti dalsi 5 bitu
add al,7 ;pricti ztracenych 7
cmp al,38 ;pokracuj kdyz to da dohromady 38
jnz crd_ok
cread al,8 ;nacti 8 bitu
add eax,38 ;a pricti 38
cmp eax,293 ;pokracuj kdyz to da 293
jnz crd_ok
cread al,8 ;precti dalsi 8 bitu
cread ah,8 ;Nejdriv dolni a pak horni
add eax,293
crd_ok: rol ecx,16 ;obnov cx
endm
public cread0_
cread0_: and ecx,0ffffh ;vynuluj horni pulku ecx
xor edx,edx ;vynuluj pamet bitu
cread_ax ;precti prvni zaznam
or eax,eax ;je li 0 zaciname jednickami
jnz cread0a
cread0c: cread_ax ;precti zaznam
inc eax ;+1
cread0b: xor [edi],bx ;invertuj rovinu
add edi,2
dec ecx ;odecitej ecx
dec eax ;odecti citac
jnz cread0b ;dokud neni ax=0
or cx,cx ;kontrola zda nejsme na konci
jz cread0e ;kdyz ne
cread_ax ;precti dalsi zaznam
inc eax ;+1
cread0a: sub cx,ax ;ted se jenom preskoci
jz cread0e ;ale kdyz jsme na konci tak nic nedelej
shl eax,1 ;preskoci 2*eax bajtu
add edi,eax ;skok!
jmp cread0c ;a jedem znova.
cread0e: ret
public cread1_
cread1_: and ecx,0ffffh
xor edx,edx
cread1a: cread_ax ;cti zaznam
add edi,eax ;preskoc EAX bajtu a zapis 1
xor [edi],ebx
add edi,2
dec ecx ;jedna za jeden bod
sub cx,ax ;a jeste ax bajtu
jnz cread1a ;jeste to neni vse?
ret
public cread2_
cread2_: and ecx,0ffffh
xor edx,edx
cread2a: cread_ax ;cti zaznam
add edi,eax ;zapis EAX bajtu a preskoc 1
cread2b: xor [edi],ebx
add edi,2
dec ecx ;jedna za jeden bod
dec eax
jnz cread2b
add edi,2
dec ecx
jnz cread2a
ret
public cread3_
cread3_: mov dh,8 ;dh - citac bitu
mov dl,[esi] ;vezmi prvni osmici
inc esi ;zvys adresu
cread3b: shl dl,1 ;nacti bit do cf
sbb eax,eax ;je-li nastaven je vysledek 0xffffffff
and eax,ebx ;nastav prislusnou rovinu
xor [edi],ax ;proved XOR
add edi,2 ;dalsi bod
dec ecx ;odecti si ho
jz cread3a ;kdyz uz jsme na konci skok na cread3a
dec dh ;odecti citac bitu
jz cread3_ ;jakmile klesne na nulu zacni od zacatku
jmp cread3b ;jinak opakuj.
cread3a: ret
_TEXT ends
END

16
VIDEO/BITLINE.H Normal file
View file

@ -0,0 +1,16 @@
void *cmode0(void *source,void *target,int count,int rovina);
#pragma aux cmode0 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cmode1(void *source,void *target,int count,int rovina);
#pragma aux cmode1 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cmode2(void *source,void *target,int count,int rovina);
#pragma aux cmode2 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cmode3(void *source,void *target,int count,int rovina);
#pragma aux cmode3 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cread0(void *source,void *target,int count,int rovina);
#pragma aux cread0 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cread1(void *source,void *target,int count,int rovina);
#pragma aux cread1 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cread2(void *source,void *target,int count,int rovina);
#pragma aux cread2 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];
void *cread3(void *source,void *target,int count,int rovina);
#pragma aux cread3 parm [ESI][EDI][ECX][EBX] modify [EAX EDX] value [EDI];

BIN
VIDEO/BOLDCZ.FON Normal file

Binary file not shown.

8
VIDEO/CINEMA.H Normal file
View file

@ -0,0 +1,8 @@
#define TRACK_VIDEO 1
#define TRACK_PALETTE 2
#define TRACK_MUSIC 3
#define TRACK_DELAY 4
#define TRACK_CLEAR 5
#define TRACK_END 0xff

667
VIDEO/CNMBUILD.C Normal file
View file

@ -0,0 +1,667 @@
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
#include <memman.h>
#include <bgraph.h>
#include "flc.h"
#include "anipack.h"
#include <conio.h>
#include "cinema.h"
#define BOX_X 8
#define BOX_Y 8
typedef int T_BOX[BOX_X*BOX_Y];
typedef char PALETA[256][3];
PALETA cur_pal;
int box_end;
T_BOX cur_box;
T_BOX sort_box;
char box_data[BOX_X*BOX_Y],conv_data[BOX_X*BOX_Y];
char last_boxes[80][23][BOX_X*BOX_Y];
char preview=1;
char pack_repeat=0;
char *flc_name;
char vystup[120000];
char differs[120000];
char *ip;
char bit_mode;
char same;
FILE *anim;
char *anim_name;
word new_paleta[256],old_paleta[256];
word play_screen[240000];
int per_frame=60000;
int old_per_box;
char rastry=1;
int rastry_rozliseni=100;
int per_box;
int now_calc_size;
int hranice_velikosti[][2]={
{2,0},
{11,1},
{20,2},
{21,2},
{30,3},
{31,3},
{32,3},
{33,3},
{42,4},
{43,4},
{44,4},
{45,4},
{46,4},
{47,4},
{48,4},
{49,4},
};
char compress_table[]={0,0,1,2,2,3,3,3,3,4,4,4,4,4,4,4};
//char compress_table[]={0,0,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,};
//char compress_table[]={0,0,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,};
int hranice=0;
int get_distance(int col1,int col2)
{
return abs(cur_pal[col1][0]-cur_pal[col2][0])+
abs(cur_pal[col1][1]-cur_pal[col2][1])+
abs(cur_pal[col1][2]-cur_pal[col2][2]);
}
void create_differs()
{
word *c;
char *d,*e;
int i;
int j,k,x;
j=0;k=0x7fffffff;
for(i=1;i<256;i++)
if ((x=get_distance(0,i))<=
k)
{
k=x;j=i;
}
c=play_screen;
d=frame_buffer;
e=differs;
for(i=0;i<120000;i++,c++,d++,e++)
{
if (!*d) *d=j;
if (*c!=new_paleta[*d])
*e=*d;
else
*e=0;
}
}
void box_read(int xbox,int ybox)
{
int x,y,k;
char *a,*bd;
same=1;
box_end=0;
bd=box_data;
a=differs;
memset(cur_box,0xff,sizeof(cur_box));
xbox=BOX_X*xbox;
ybox=BOX_Y*ybox;
a+=640*ybox+xbox;
for(y=ybox;y<ybox+BOX_Y;y++,a+=640-BOX_X)
for(x=xbox;x<xbox+BOX_X;x++,a++)
{
for(k=0;k<box_end && cur_box[k]!=*a;k++);
if (k==box_end) cur_box[box_end++]=*a;
*bd++=*a;
}
}
void conv_pal_hicolor()
{
int i,r,g,b;
memcpy(old_paleta,new_paleta,sizeof(new_paleta));
for(i=0;i<256;i++)
{
r=(flc_paleta[i][0]>>3);
g=(flc_paleta[i][1]>>3);
b=(flc_paleta[i][2]>>3);
new_paleta[i]=(r<<10)+(g<<5)+b;
}
memcpy(cur_pal,flc_paleta,sizeof(flc_paleta));
new_paleta[0]=0x8000;
}
/*
void set_vga_palette()
{
int x;
char *c;
c=cur_pal;
outp (0x3c8
, 0);
for (x=0; x<768; x++,c++)
{
while (inp(0x3da) & 1);
while (!(inp(0x3da) & 1));
outp (0x3c9,*c);
}
}
void get_vga_palette()
{
int x;
char *c;
c=cur_pal;
outp (0x3c7, 0);
for (x=0; x<768; x++,c++)
{
while (inp(0x3da) & 1);
while (!(inp(0x3da) & 1));
*c=inp (0x3c9);
}
cur_pal[0][0]=0;
cur_pal[0][1]=0;
cur_pal[0][2]=0;}
*/
/*void box_analize()
{
int i,c;
int r,g,b;
for(i=0;i<box_end;i++)
{
c=cur_box[i].color;
r=cur_pal[c][0];
g=cur_pal[c][1];
b=cur_pal[c][2];
cur_box[i].distance=r+g+b;
}
}
*/
void box_sort()
{
int c;
int i,max,j,ds,d,a,z;
d=0;
a=0;z=2;
c=cur_box[a];
sort_box[0]=c;
do
{
max=0;j=-1;
for(i=0;i<box_end;i++)
{
if (cur_box[i]==0)
{
j=i;
break;
}
if (cur_box[i]>=0 && (ds=get_distance(c,cur_box[i]))>max)
{
j=i;max=ds;
}
}
if (j>=0)
{
c=cur_box[j];
sort_box[d++]=c;
cur_box[j]=-1;
a=j;
}
if (max>hranice)
{
z=d;
}
}
while (j!=-1);
if (box_end>1) box_end=z;
}
int zvol_metodu()
{
int i=0;
for(;hranice_velikosti[i][0]<per_box;i++);
return i;
}
void store_palette()
{
int bits,palsize,i;
bits=compress_table[box_end];
palsize=1<<bits;
box_end=palsize;
bit_mode=bits;
if (box_end<palsize && box_end) palsize=box_end;
if (palsize==1 && sort_box[0]==0)
{
ip-=2;
if (pack_repeat && ip[1]<255 && ip[0]<2)
{
ip[0]=0;
ip[1]++;
ip+=2;
}
else
{
ip+=2;
*ip++=0;
*ip++=0;
pack_repeat=1;
}
return;
}
pack_repeat=0;
*ip++=palsize;
for(i=0;i<palsize;i++) *ip++=sort_box[i];
}
/*
void box_test_same(int xbox,int ybox)
{
int x,y;
char *c,*d;
same=0;
c=play_screen;
d=conv_data;
xbox=BOX_X*xbox;
ybox=BOX_Y*ybox;
c+=640*ybox+xbox;
for(y=ybox;y<ybox+BOX_Y;y++,c+=640-BOX_X)
for(x=xbox;x<xbox+BOX_X;x++,c++)
if (*c!=*d++) return;
same=1;
}
*/
void conv_box(int x,int y)
{
int i,j,max,indx,indx2,ds;
char c;
int tab[256];
int subst[256];
int dst[256];
x,y,dst;
memset(tab,0xff,sizeof(tab));
memset(subst,0xff,sizeof(subst));
tab[0]=0;
subst[0]=0;
for(i=0;i<BOX_X*BOX_Y;i++)
{
c=box_data[i];
if (tab[c]==-1)
{
max=0x7fffffff;indx=0;indx2=-1;
for(j=(sort_box[0]==0);j<box_end;j++)
{
if (c==sort_box[j] && c)
{
indx=j;
indx2=j;
max=0;
break;
}
if (sort_box[j] && (ds=get_distance(c,sort_box[j]))<max)
{
if (indx) indx2=indx;
max=ds;
indx=j;
}
}
if (indx2==-1) indx2=indx;
tab[c]=indx;
subst[c]=indx2;
dst[c]=max;
}
else
{
indx=tab[c];
indx2=subst[c];
}
if (sort_box[0]==0 && indx2==0 && indx!=0)
exit(0);
else
if (sort_box[0]==0 && indx2!=0 && indx==0)
exit(0);
if (rastry && indx!=indx2 && get_distance(sort_box[indx],sort_box[indx2])<rastry_rozliseni && (((i>>1) & 1) ^ ((i>>3) & 1)) && indx2!=-1) indx=subst[c];
if (sort_box[0]==0 && c && last_boxes[x][y][i]!=0 && get_distance(c,last_boxes[x][y][i])<dst[c])
{
indx=0;
}
else
if (box_data[i]) last_boxes[x][y][i]=sort_box[indx];
box_data[i]=indx;
conv_data[i]=sort_box[indx];
}
}
void save_box(int x,int y)
{
char bits;
if (box_end>=sizeof(compress_table))
{
int i;
*ip++=64;
memcpy(ip,box_data,sizeof(box_data));
memcpy(conv_data,box_data,sizeof(box_data));
for(i=0;i<sizeof(box_data);i++)
if (box_data[i])last_boxes[x][y][i]=box_data[i];
ip+=sizeof(box_data);
pack_repeat=0;
}
else
{
store_palette();
conv_box(x,y);
bits=bit_mode;
switch (bits)
{
case 1:ip=save_1bit(&box_data,ip);break;
case 2:ip=save_2bit(&box_data,ip);break;
case 3:ip=save_3bit(&box_data,ip);break;
case 4:ip=save_4bit(&box_data,ip);break;
}
}
}
void conv_complette(int x,int y)
{
int i;
box_read(x,y);
box_sort();
if (box_end>(i=zvol_metodu())) box_end=i;
save_box(x,y);
}
void conv_pict()
{
int i,j,count=0;
pack_repeat=0;
now_calc_size=0;
conv_pal_hicolor();
create_differs();
ip=vystup;
old_per_box=-1;
for(i=0;i<23;i++)
for(j=0;j<80;j++)
{
per_box=(per_frame-(ip-vystup))/(80*23-count);
if (old_per_box==-1) old_per_box=per_box;else if (per_box>old_per_box)per_box+=(per_box-old_per_box);
count++;
conv_complette(j,i);
}
}
/*
void decompr_box(word *adr)
{
char mode;
word palxlat[16];
int i;
mode=*ip++;
if (mode==255) return;
if (mode<64)
{
for(i=0;i<mode;i++) palxlat[i]=new_paleta[*ip++];
mode=hranice_velikosti[mode-1][1];
}
else mode=8;
switch (mode)
{
case 0:load_0bit(adr,palxlat);break;
case 1:ip=load_1bit(ip,adr,palxlat);break;
case 2:ip=load_2bit(ip,adr,palxlat);break;
case 3:ip=load_3bit(ip,adr,palxlat);break;
case 4:ip=load_4bit(ip,adr,palxlat);break;
case 8:ip=load_8bit(ip,adr,new_paleta);break;
}
}
void decompr_pict()
{
int x;
int y;
ip=vystup;
for (y=0;y<115200;y+=640*8)
for (x=0;x<640;x+=8)
decompr_box(play_screen+x+y);
}
*/
void adjust_pict()
{
int i,j,k,l;
for(i=0;i<24;i++)
for(j=0;j<80;j++)
for(k=0;k<8;k++)
for(l=0;l<8;l++)
play_screen[(i*8+k)*640+(j*8+l)]=new_paleta[last_boxes[j][i][k*8+l]];
}
void show_play_screen()
{
int i,j;
word *c,*d;
c=lbuffer;j=0;
c+=(60)*640;
d=play_screen;
for(i=0;i<180;i++)
{
memcpy(c,d,1280);
c+=640*2;
d+=640;
}
d=play_screen;
c=lbuffer+61*640;
delay(30);
for(i=0;i<180;i++)
{
for(j=0;j<320;j++)
{
*(unsigned long *)c=((*(unsigned long *)d & 0x7BDE7BDE)+(*(unsigned long *)(d+640) & 0x7BDE7BDE))>>1;
c+=2;
d+=2;
}
c+=640;
}
}
void save_palette()
{
int i,il,ip,ps;
for(i=0;i<256 && old_paleta[i]==new_paleta[i];i++);
il=i;
if (il==256) ip=il;
else
{
for(i=255;i>0 && old_paleta[i]==new_paleta[i];i--);
ip=i+1;
}
ps=ip-il;
if (ps)
{
i=TRACK_PALETTE;
fwrite(&i,1,1,anim);
fwrite(&il,1,2,anim);
fwrite(&ps,1,2,anim);
fwrite(&new_paleta[il],sizeof(word),ps,anim);
}
}
void save_frame(int size)
{
int i;
i=TRACK_VIDEO;
fwrite(&i,1,1,anim);
fwrite(&size,1,sizeof(size),anim);
fwrite(vystup,1,size,anim);
}
void save_mark(int i)
{
fwrite(&i,1,1,anim);
}
void int10_3();
#pragma aux int10_3=\
"mov eax,3"\
"int 10h"\
modify [eax];
void int10_13();
#pragma aux int10_13=\
"mov eax,13h"\
"int 10h"\
modify [eax];
void pack_anim()
{
int x;int size;
Open_FLC(flc_name);
Get_first_frame();
Decompress_frame();
conv_pict();
adjust_pict();
if (preview) show_play_screen();
size=ip-vystup;printf("Frame 1: %d \n",size);
save_palette();
save_frame(size);
for (x=2; x<=h_flc.frames+10; x++)
{
if (x<=h_flc.frames)
{
Get_next_frame ();
Decompress_frame ();
if (preview) show_play_screen();
}
conv_pict();
adjust_pict();
size=ip-vystup;printf("Frame %d: %d \n",x,size);
save_palette();
save_frame(size);
save_mark(TRACK_DELAY);
}
save_mark(TRACK_END);
}
/*
decompr_pict();
show_play_screen();
getch();
decompr_pict();
show_play_screen();
*/
void load_frame()
{
int size;
fread(&size,1,sizeof(size),anim);
fread(vystup,1,size,anim);
}
void load_palette()
{
word i;
word size;
fread(&i,1,2,anim);
fread(&size,1,2,anim);
fread(&new_paleta[i],2,size,anim);
}
/*
char play_track(FILE *anim)
{
char i;
fread(&i,1,1,anim);
switch (i)
{
case TRACK_VIDEO:
load_frame();
decompr_pict();
break;
case TRACK_PALETTE:
load_palette();
break;
case TRACK_MUSIC:break;
case TRACK_END:return 0;
case TRACK_DELAY:
show_play_screen();
// delay(7);
break;
}
return 1;
}
void play_anim(FILE *anim)
{
while(play_track(anim));
}
*/
main(int argc,char *argv[])
{
if (argc<3)
{
puts("");
puts("Poziti: cnmbuild filename.flc filename.cnm [perframe] [rastry]");
puts("");
puts("perframe - omezeni velikosti na jeden frame");
puts("rastry - cislo udavajici hranici pro rastrovani (0 - bez rastru)");
return 1;
}
memset(play_screen,0xff,sizeof(play_screen));
memset(frame_buffer,0xff,sizeof(frame_buffer));
memset(new_paleta,0xff,sizeof(new_paleta));
memset(last_boxes,0,sizeof(last_boxes));
flc_name=argv[1];
anim_name=argv[2];
if (argc>=4) sscanf(argv[3],"%d",&per_frame);
if (argc>=5) sscanf(argv[4],"%d",&rastry_rozliseni);
if (initmode32(NULL)) preview=0;
if (banking)
{
closemode();preview=0;
}
anim=fopen(anim_name,"wb");
pack_anim();
fclose(anim);
closemode();
return 0;
}

74
VIDEO/CNMCONTR.C Normal file
View file

@ -0,0 +1,74 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <bgraph.h>
#define ERR_PARM 1
#define ERR_STR 2
#define ERR_NUMB 3
typedef struct command_table
{
char command[20];
void (*proc)(int frame);
}COMMAND_TABLE
int total_commands=0;
char paramstr[200];
int cur_line;
char command[50];
char errors[]="Ok.,Nespravny pocet parametru.,Chybi konec retezce.,Chybna hodnota.";
void extract_text(char *what,int num,char *s)
{
char *c;
char ii=0;
c=what;
while (num && *c)
{
if (!*c) call_error(ERR_PARM);
if (*c=='\"') ii=!ii;
else if (*c==',' && !ii) num--;
c++
}
while((*c!=',' && *c) || ii)
{
if (!*c) call_error(ERR_STR);
if (*c=='\"') ii=!ii;
*s++=*c++
}
}
void odstran_uvozovky(char *s)
{
char *c;
char iif=0;
c=s;
while (*s)
{
if (*s!='\"' || iif)
{
*c++=*s;
iif=0;
}
else
iif=1;
}
}
int conv_to_int(char *s)
{
int i;
if (sscanf(s,"%d",&i)!=1) return i;
call_error(ERR_NUMB)
}

202
VIDEO/FLC.C Normal file
View file

@ -0,0 +1,202 @@
//
// Knihovna pro dekompresi FLC souboru
//
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
#include <i86.h>
#include "flc.h"
FILE *flc;
flcheader h_flc;
frameheader h_frame;
actionheader h_action;
char flc_paleta[256][3];
char frame_buffer [307205];
char *flc_buffer;
char test=1;
void Open_FLC (char *filename)
{
flc = fopen (filename, "rb");
fread (&h_flc, sizeof(flcheader), 1, flc);
}
void Close_FLC (void)
{
fclose (flc);
free (flc_buffer);
}
void Get_first_frame (void)
{
fseek (flc, h_flc.offset1, SEEK_SET);
fread (&h_frame, sizeof(frameheader), 1, flc);
flc_buffer = (char*)malloc((h_frame.size-sizeof(frameheader)));
fread (flc_buffer, (h_frame.size-sizeof(frameheader)), 1, flc);
}
void Get_next_frame (void)
{
free (flc_buffer);
fread (&h_frame, sizeof(frameheader), 1, flc);
flc_buffer = (char*)malloc((h_frame.size-sizeof(frameheader)));
fread (flc_buffer, (h_frame.size-sizeof(frameheader)), 1, flc);
}
void Decompress_frame (void)
{
unsigned short x,y,z,w;
unsigned short changes, nfo_word, packets, offset, row;
int frame_pos=0,tst;
unsigned int scr_pos;
char c1, c2, c3, a;
char hi, lo;
packets=0;
for (z=1; z<=h_frame.actions; z++)
{
memmove ( &h_action, (flc_buffer+frame_pos), sizeof(actionheader) );
switch (h_action.code)
{
case 16:
frame_pos+=6;
memcpy(frame_buffer,flc_buffer+
frame_pos,h_flc.width*h_flc.height);
frame_pos+=h_flc.width*h_flc.height;
break;
case 4:
{
short bc;
int barv,poc;
int fp;
fp=frame_pos+6;
bc=*(short *)(flc_buffer+fp);fp+=2;
barv=0;
while(bc--)
{
barv+=(flc_buffer[fp++]);
poc=(char)(flc_buffer[fp++]-1)+1;
memcpy(&flc_paleta[barv][0],flc_buffer+fp,poc*3);
fp+=poc*3;barv+=poc;
}
frame_pos+=h_action.size;
}
break;
case 7:
case 12:
frame_pos+=6;
lo=flc_buffer[frame_pos]; frame_pos++;
hi=flc_buffer[frame_pos++];
changes=hi*256+lo;
row=0;tst=frame_pos+h_action.size;
for (y=0; frame_pos<tst ; y++) // pocet menenych radek
{
lo=flc_buffer[frame_pos]; frame_pos++;
hi=flc_buffer[frame_pos++];
nfo_word=hi*256+lo;
scr_pos=row*h_flc.width/*640*/;
if (nfo_word>=0x8000) // preskakovane radky
{
nfo_word=(short)(-nfo_word); //0xFFFF-nfo_word+1;
row+=nfo_word;
}
else
{
for (z=0; z<nfo_word; z++) // pocet menenych bloku
{
x=1; a=0;
offset = flc_buffer[frame_pos]; // rel. offset bloku
frame_pos++;
scr_pos+=offset;
// while (!a) // zmena bloku
// {
c1 = flc_buffer[frame_pos];
frame_pos++;
if (frame_pos>=tst) break;
if (c1>128)
{
c1=0xFF-c1+1;
c2=flc_buffer[frame_pos];
frame_pos++;
c3=flc_buffer[frame_pos];
frame_pos++;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=c2;
scr_pos++;
frame_buffer[scr_pos]=c3;
scr_pos++; }
}
else
{
// c3=0xFF-c3+1;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=flc_buffer[frame_pos];
frame_pos++;
scr_pos++;
frame_buffer[scr_pos]=flc_buffer[frame_pos];
frame_pos++;
scr_pos++; }
}
// if (x>=640) a=1;
// }
}
row++;
}
}
// frame_pos+=h_action.size;
break;
case 15:
frame_pos+=6;
for (y=0; y<=(h_flc.height-1); y++)
{
frame_pos++; x=1; //a=0;
scr_pos=y*h_flc.width;
while (x<=h_flc.width)
{
c1 = flc_buffer[frame_pos];
frame_pos++;
if (c1<128)
{
c2=flc_buffer[frame_pos];
frame_pos++;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=c2;
scr_pos++;
x++; }
}
else
{
c1=0xFF-c1+1;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=flc_buffer[frame_pos];
scr_pos++;
frame_pos++;
x++; }
}
}
}
break;
default: frame_pos+=h_action.size;
break;
};
}
}

62
VIDEO/FLC.H Normal file
View file

@ -0,0 +1,62 @@
//
// Hlavickovy soubor ke knihovne FLC.C slouzici k dekompresi FLC
//
#ifndef _FLC_H
#define _FLC_H
typedef struct FLCHEADER {
unsigned int size; // delka souboru vcetne hlavicky
unsigned short idflc; // ID FLC=0AF12h
unsigned short frames; // pocet frejmu
unsigned short width; // sirka vsech obrazku
unsigned short height; // vyska vsech obrazku
unsigned short color; // hloubka barvy (bpp)
unsigned short flag1;
unsigned int speed; // rychlost prehravani (v 1/1000 s)
unsigned short reserv1; // rezervovany
unsigned int date1; // datum a cas vytvoreni
unsigned int serial; // seriove cislo programu
unsigned int date2; // datum a cas posledni zmeny
unsigned short XA;
unsigned short YA;
char reserv2 [42]; // rezervovano
unsigned int offset1; // offset prvniho frame
unsigned int offset2; // offset druheho frame
char reserv3 [40]; // rezervovano
} flcheader;
typedef struct FRAMEHEADER {
unsigned int size; // velikost frame v bytech
unsigned short sign; // znacka frame OFAF1h
unsigned short actions; // pocet akci v tomto frame
char reserv [8]; // rezervovano
} frameheader;
typedef struct ACTIONHEADER {
unsigned int size; // velikost akce v bytech
unsigned short code; // kod akce
// 04h - predani casti nebo cele palety
// 07h - predavani zmenenych casti obrazu
// 0Dh - vymaze obrazovku
// 0Fh - cela obrazovka v RLE
// 10h - nekomprimovana kopie cele obrazovky
// nasleduji data akce
} actionheader;
extern FILE *flc;
extern flcheader h_flc;
extern frameheader h_frame;
extern actionheader h_action;
extern char frame_buffer [307205];
extern char *flc_buffer;
extern char flc_paleta[256][3];
//unsigned int ladici;
void Open_FLC (char *filename);
void Close_FLC (void);
void Get_first_frame (void);
void Get_next_frame (void);
void Decompress_frame (void);
#endif

View file

@ -0,0 +1,71 @@
/*********************************************/
/*** DOS memory allocation - DOSMEM.C ***/
/*** vykostena verze chlumakova memalloc.c ***/
/*********************************************/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosmem.h"
/*** Alokace pole v dolni pameti ***/
void *mem_alloc(int size)
{
static union REGS r;
MEMREC memrec;
r.x.eax=0x0100;
r.x.ebx=(size>>4)+1;
size=r.x.ebx<<4;
int386(0x31,&r,&r);
if (r.x.cflag)
{
printf ("No fucking DOS memory left!!!");
exit(1);
}
memrec.ptr=(void *)((r.x.eax&0xFFFF)<<4);
Selector=memrec.selector=(short int)r.x.edx;
return memrec.ptr;
}
/*** Uvolneni dolni pameti ***/
void mem_free(void *ptr)
{
union REGS r;
if(ptr!=NULL)
{
r.x.eax=0x0101;
r.x.edx=Selector;
int386(0x31,&r,&r);
if(r.x.cflag)
printf("Cannot free DOS memory!!!!");
}
}
/*** Vyvolani preruseni pomoci protected modu ***/
void WtNs386(int IntNum, DPMIREGS *dpmiregs)
{
union REGS r;
struct SREGS sr;
r.w.ax=0x300;
r.h.bl=(char)IntNum;
r.h.bh=0;
r.w.cx=0;
segread(&sr);
sr.es=FP_SEG(dpmiregs);
r.x.edi=FP_OFF(dpmiregs);
int386x(0x31,&r,&r,&sr);
}

View file

@ -0,0 +1,46 @@
/************************************/
/*** Hlavickovt soubor k DOSMEM.H ***/
/************************************/
typedef enum
{ DOS_MEMORY,
NEW,
} MEMORY_ITEMS;
typedef struct
{ int EDI;
int ESI;
int EBP;
int reserved;
int EBX;
int EDX;
int ECX;
int EAX;
short int Flags;
short int ES;
short int DS;
short int GS;
short int IP;
short int CS;
short int SP;
short int SS;
} DPMIREGS;
typedef struct
{ void *ptr;
int size;
int selector; //smysl jen u DOS_MEMORY
} MEMREC;
#define D32RealSeg(P) ((((unsigned int)(P))>>4)&0xFFFF)
#define D32RealOff(P) (((unsigned int)(P))&0xF)
int Selector;
DPMIREGS dpmiregs;
void *mem_alloc(int size);
void mem_free(void *ptr);
void WtNs386(int IntNum, DPMIREGS *dpmiregs);

5
VIDEO/FLC/ANALYSE/FLC.C Normal file
View file

@ -0,0 +1,5 @@
//
// Knihovna pro dekompresi FLC souboru
//
#include "flc.h"

54
VIDEO/FLC/ANALYSE/FLC.H Normal file
View file

@ -0,0 +1,54 @@
//
// Hlavickovy soubor ke knihovne FLC.C slouzici k dekompresi FLC
//
#ifndef _FLC_H
#define _FLC_H
typedef struct FLCHEADER {
unsigned int size; // delka souboru vcetne hlavicky
unsigned short idflc; // ID FLC=0AF12h
unsigned short frames; // pocet frejmu
unsigned short width; // sirka vsech obrazku
unsigned short height; // vyska vsech obrazku
unsigned short color; // hloubka barvy (bpp)
unsigned short flag1;
unsigned int speed; // rychlost prehravani (v 1/1000 s)
unsigned short reserv1; // rezervovany
unsigned int date1; // datum a cas vytvoreni
unsigned int serial; // seriove cislo programu
unsigned int date2; // datum a cas posledni zmeny
unsigned short XA;
unsigned short YA;
char reserv2 [42]; // rezervovano
unsigned int offset1; // offset prvniho frame
unsigned int offset2; // offset druheho frame
char reserv3 [40]; // rezervovano
} flcheader;
typedef struct FRAMEHEADER {
unsigned int size; // velikost frame v bytech
unsigned short sign; // znacka frame OFAF1h
unsigned short actions; // pocet akci v tomto frame
char reserv [8]; // rezervovano
} frameheader;
typedef struct ACTIONHEADER {
unsigned int size; // velikost akce v bytech
unsigned short code; // kod akce
// 04h - predani casti nebo cele palety
// 07h - predavani zmenenych casti obrazu
// 0Dh - vymaze obrazovku
// 0Fh - cela obrazovka v RLE
// 10h - nekomprimovana kopie cele obrazovky
// nasleduji data akce
} actionheader;
char frame_buffer [307200];
char *flc_buffer;
void Get_first_frame (void);
void Get_next_frame (void);
void Decompress_frame (void);
#endif

54
VIDEO/FLC/ANALYSE/PLAY.C Normal file
View file

@ -0,0 +1,54 @@
#include <stdio.h>
#include <conio.h>
#include <graph.h>
#include "flc.h"
flcheader h_flc;
frameheader h_frame;
actionheader h_action;
void main (int argc, char *argv[])
{
FILE *flc;
long pozice;
int frames, actions, x, y;
flc = fopen (argv[1], "rb");
fread (&h_flc, sizeof(flcheader), 1, flc);
frames=h_flc.frames;
printf ("\nHlavicka FLC souboru %s:\n", argv[1]);
printf ("Delka celeho souboru: %d\n", h_flc.size);
printf ("Pocet frame: %d\n", h_flc.frames);
printf ("Velikost filmu: %dx%d\n", h_flc.width, h_flc.height);
printf ("Hloubka barvy: %d\n", h_flc.color);
printf ("Rychlost prehravani: %d fps\n", 1000/h_flc.speed);
printf ("Offset prvniho frame: %d\n", h_flc.offset1);
fseek (flc, h_flc.offset1, SEEK_SET);
for (x=0; x<=(frames-1); x++)
{
fread (&h_frame, sizeof(frameheader), 1, flc);
actions=h_frame.actions;
printf ("\nHlavicka %d framu:\n", x+1);
printf ("Velikost framu: %d\n", h_frame.size);
printf ("Pocet akci ve framu: %d\n", h_frame.actions);
for (y=0; y<=(actions-1); y++)
{
pozice = ftell (flc);
fread (&h_action, sizeof(actionheader), 1, flc);
fseek (flc, (pozice+h_action.size), SEEK_SET);
printf ("\nHlavicka %d akce:\n", y+1);
printf ("Velikost dat pro tuto akci: %d\n", h_action.size);
printf ("Kod akce: %x\n", h_action.code);
}
getch ();
_clearscreen (_GCLEARSCREEN);
}
fclose (flc);
}

296
VIDEO/FLC/ANALYSE/VESA.C Normal file
View file

@ -0,0 +1,296 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "vesa.h"
#include "dosmem.h"
extern void wm_ChangeBank_(int bank);
#pragma aux (ASM) wm_ChangeBank_;
void Set_VESA_mode (int mode)
{
union REGS r;
r.w.ax=0x4f02;
r.w.bx=mode;
int386 (0x10, &r, &r);
}
void Show_screen (char *display)
{
wm_ChangeBank_ (0);
memmove (0xa0000, display, 65536);
wm_ChangeBank_ (1);
memmove (0xa0000, (display+65536), 65536);
wm_ChangeBank_ (2);
memmove (0xa0000, (display+131072), 65536);
wm_ChangeBank_ (3);
memmove (0xa0000, (display+196608), 65536);
wm_ChangeBank_ (4);
memmove (0xa0000, (display+262144), 45056);
}
void Put_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
break;
};
}
}
void Get_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
break;
};
}
}
void Get_VESA_info (void)
{
char far *str;
VESA_INFO_BLOCK *p;
p=(VESA_INFO_BLOCK *)mem_alloc(sizeof(VESA_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS));
dpmiregs.EAX=0x00004f00;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaInfoBlock,str,sizeof(VESA_INFO_BLOCK));
mem_free(p);
if(dpmiregs.EAX!=0x4f)
{
printf ("VESA Bios extension not found!!!!");
exit (1);
}
}
void Get_mode_info (int mode)
{
char far *str;
VESA_MODE_INFO_BLOCK *p;
p=(VESA_MODE_INFO_BLOCK *)mem_alloc(sizeof(VESA_MODE_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS)); //nuluje registry
dpmiregs.EAX=0x00004f01;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
dpmiregs.ECX=mode;
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaModeInfoBlock,str,sizeof(VESA_INFO_BLOCK));
_VGAGran=VesaModeInfoBlock.WinGranularity;
mem_free(p);
}

70
VIDEO/FLC/ANALYSE/VESA.H Normal file
View file

@ -0,0 +1,70 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#ifndef __VESA_H
#define __VESA_H
typedef struct
{ char VESASignature[4];
short VESAversion;
unsigned OEMStringPtr;
char capabilities[4];
short int *videomodeptr;
short int TotalMemory;
char dummy[236];
} VESA_INFO_BLOCK;
typedef struct
{ short unsigned ModeAttributes;
char WinAAttributes;
char WinBAttributes;
short unsigned WinGranularity;
short unsigned WinSize;
short unsigned WinASegment;
short unsigned WinBSegment;
short unsigned WinFuncPtroff;
short unsigned WinFuncPtrseg;
short unsigned BytesPerScanLine;
short unsigned XResolution;
short unsigned YResolution;
char Xcharsize;
char Ycharsize;
char NumberOfPlanes;
char BitsPerPixel;
char NumberOfBanks;
char MemoryModel;
char BankSize;
char NumberOfImagePages;
char Reserved;
char RedMaskSize;
char RedFieldPosition;
char GreenMaskSize;
char GreenFieldPosition;
char BlueMaskSize;
char BlueFieldPosition;
char RsvdMaskSize;
char DirectColorModeInfo;
char Dummy[216];
} VESA_MODE_INFO_BLOCK;
VESA_MODE_INFO_BLOCK VesaModeInfoBlock;
VESA_INFO_BLOCK VesaInfoBlock;
extern unsigned char _VGAPage=0;
extern unsigned char _VGAGran=0;
void Set_VESA_mode (int mode);
void Show_screen (char *display);
void Get_VESA_info (void);
void Get_mode_info (int mode);
void Put_image (int x, int y, int xlen, int ylen, char *image);
void Get_image (int x, int y, int xlen, int ylen, char *image);
#endif

View file

@ -0,0 +1,63 @@
;EAX EDX EBX ECX
.386p
jumps
;############################################################################
; Constanty
;############################################################################
dlt_x equ 640
dlt_y equ 480
;############################################################################
; Datovy segment
;############################################################################
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
align 4
EXTRN __VGAPage:BYTE
EXTRN __VGAGran:BYTE
_DATA ENDS
DGROUP GROUP _DATA
;############################################################################
; Kodovy segment
;############################################################################
_TEXT SEGMENT PARA PUBLIC USE32 'CODE'
ASSUME cs:_TEXT, ds:_DATA
public wm_ChangeBank__
wm_ChangeBank__ PROC
push es
pushad
push eax
mov edx, eax
mov ebx, 0000h
mov eax, 4f05h
int 10h
pop eax
mov edx, eax
mov ebx, 0001h
mov eax, 4f05h
int 10h
popad
pop es
ret
wm_ChangeBank__ endp
;----------------------------------------------------------------------------
_TEXT ENDS
END

71
VIDEO/FLC/DOSMEM.C Normal file
View file

@ -0,0 +1,71 @@
/*********************************************/
/*** DOS memory allocation - DOSMEM.C ***/
/*** vykostena verze chlumakova memalloc.c ***/
/*********************************************/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosmem.h"
/*** Alokace pole v dolni pameti ***/
void *mem_alloc(int size)
{
static union REGS r;
MEMREC memrec;
r.x.eax=0x0100;
r.x.ebx=(size>>4)+1;
size=r.x.ebx<<4;
int386(0x31,&r,&r);
if (r.x.cflag)
{
printf ("No fucking DOS memory left!!!");
exit(1);
}
memrec.ptr=(void *)((r.x.eax&0xFFFF)<<4);
Selector=memrec.selector=(short int)r.x.edx;
return memrec.ptr;
}
/*** Uvolneni dolni pameti ***/
void mem_free(void *ptr)
{
union REGS r;
if(ptr!=NULL)
{
r.x.eax=0x0101;
r.x.edx=Selector;
int386(0x31,&r,&r);
if(r.x.cflag)
printf("Cannot free DOS memory!!!!");
}
}
/*** Vyvolani preruseni pomoci protected modu ***/
void WtNs386(int IntNum, DPMIREGS *dpmiregs)
{
union REGS r;
struct SREGS sr;
r.w.ax=0x300;
r.h.bl=(char)IntNum;
r.h.bh=0;
r.w.cx=0;
segread(&sr);
sr.es=FP_SEG(dpmiregs);
r.x.edi=FP_OFF(dpmiregs);
int386x(0x31,&r,&r,&sr);
}

46
VIDEO/FLC/DOSMEM.H Normal file
View file

@ -0,0 +1,46 @@
/************************************/
/*** Hlavickovt soubor k DOSMEM.H ***/
/************************************/
typedef enum
{ DOS_MEMORY,
NEW,
} MEMORY_ITEMS;
typedef struct
{ int EDI;
int ESI;
int EBP;
int reserved;
int EBX;
int EDX;
int ECX;
int EAX;
short int Flags;
short int ES;
short int DS;
short int GS;
short int IP;
short int CS;
short int SP;
short int SS;
} DPMIREGS;
typedef struct
{ void *ptr;
int size;
int selector; //smysl jen u DOS_MEMORY
} MEMREC;
#define D32RealSeg(P) ((((unsigned int)(P))>>4)&0xFFFF)
#define D32RealOff(P) (((unsigned int)(P))&0xF)
int Selector;
DPMIREGS dpmiregs;
void *mem_alloc(int size);
void mem_free(void *ptr);
void WtNs386(int IntNum, DPMIREGS *dpmiregs);

176
VIDEO/FLC/FLC.C Normal file
View file

@ -0,0 +1,176 @@
//
// Knihovna pro dekompresi FLC souboru
//
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
#include <i86.h>
#include "flc.h"
void Open_FLC (char *filename)
{
flc = fopen (filename, "rb");
fread (&h_flc, sizeof(flcheader), 1, flc);
}
void Close_FLC (void)
{
fclose (flc);
free (flc_buffer);
}
void Get_first_frame (void)
{
fseek (flc, h_flc.offset1, SEEK_SET);
fread (&h_frame, sizeof(frameheader), 1, flc);
flc_buffer = (char*)malloc((h_frame.size-sizeof(frameheader)));
fread (flc_buffer, (h_frame.size-sizeof(frameheader)), 1, flc);
}
void Get_next_frame (void)
{
free (flc_buffer);
fread (&h_frame, sizeof(frameheader), 1, flc);
flc_buffer = (char*)malloc((h_frame.size-sizeof(frameheader)));
fread (flc_buffer, (h_frame.size-sizeof(frameheader)), 1, flc);
}
void Decompress_frame (void)
{
unsigned short x,y,z,w;
unsigned short changes, nfo_word, packets, offset, row;
int frame_pos=0;
unsigned int scr_pos;
char c1, c2, c3, a;
char hi, lo;
for (z=1; z<=h_frame.actions; z++)
{
memmove ( &h_action, (flc_buffer+frame_pos), sizeof(actionheader) );
switch (h_action.code)
{
case 4:
a=1;//fcl_buffer[frame_pos];
// b=0;//flc_buffer[frame_pos];
// c=256; //0=256
frame_pos+=10;
outp (0x3c8, 0);
for (x=0; x<=768; x++) outp (0x3c9, (flc_buffer[(x+frame_pos)]/=4) );
frame_pos+=768;
break;
case 7:
frame_pos+=6;
lo=flc_buffer[frame_pos]; frame_pos++;
hi=flc_buffer[frame_pos]; frame_pos++;
changes=hi*256+lo;
row=0;
for (y=0; y<=(changes-1); y++) // pocet menenych radek
{
lo=flc_buffer[frame_pos]; frame_pos++;
hi=flc_buffer[frame_pos]; frame_pos++;
nfo_word=hi*256+lo;
scr_pos=row*h_flc.width;
if (nfo_word>=0xC000) // preskakovane radky
{
nfo_word=0xFFFF-nfo_word+1;
row+=nfo_word;
}
else
{
for (z=1; z<=nfo_word; z++) // pocet menenych bloku
{
x=1; a=0;
offset = flc_buffer[frame_pos]; // rel. offset bloku
frame_pos++;
scr_pos+=offset;
// while (!a) // zmena bloku
// {
c1 = flc_buffer[frame_pos];
frame_pos++;
if (c1>128)
{
c1=0xFF-c1+1;
c2=flc_buffer[frame_pos];
frame_pos++;
c3=flc_buffer[frame_pos];
frame_pos++;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=c2;
scr_pos++;
frame_buffer[scr_pos]=c3;
scr_pos++; }
}
else
{
// c3=0xFF-c3+1;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=flc_buffer[frame_pos];
frame_pos++;
scr_pos++;
frame_buffer[scr_pos]=flc_buffer[frame_pos];
frame_pos++;
scr_pos++; }
}
// if (x>=640) a=1;
// }
}
row++;
}
}
// frame_pos+=h_action.size;
break;
case 15:
frame_pos+=6;
for (y=0; y<=(h_flc.height-1); y++)
{
frame_pos++; x=1; //a=0;
scr_pos=y*h_flc.width;
while (x<=h_flc.width)
{
c1 = flc_buffer[frame_pos];
frame_pos++;
if (c1<128)
{
c2=flc_buffer[frame_pos];
frame_pos++;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=c2;
scr_pos++;
x++; }
}
else
{
c1=0xFF-c1+1;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=flc_buffer[frame_pos];
scr_pos++;
frame_pos++;
x++; }
}
}
}
break;
default: frame_pos+=h_action.size;
break;
};
}
}

61
VIDEO/FLC/FLC.H Normal file
View file

@ -0,0 +1,61 @@
//
// Hlavickovy soubor ke knihovne FLC.C slouzici k dekompresi FLC
//
#ifndef _FLC_H
#define _FLC_H
typedef struct FLCHEADER {
unsigned int size; // delka souboru vcetne hlavicky
unsigned short idflc; // ID FLC=0AF12h
unsigned short frames; // pocet frejmu
unsigned short width; // sirka vsech obrazku
unsigned short height; // vyska vsech obrazku
unsigned short color; // hloubka barvy (bpp)
unsigned short flag1;
unsigned int speed; // rychlost prehravani (v 1/1000 s)
unsigned short reserv1; // rezervovany
unsigned int date1; // datum a cas vytvoreni
unsigned int serial; // seriove cislo programu
unsigned int date2; // datum a cas posledni zmeny
unsigned short XA;
unsigned short YA;
char reserv2 [42]; // rezervovano
unsigned int offset1; // offset prvniho frame
unsigned int offset2; // offset druheho frame
char reserv3 [40]; // rezervovano
} flcheader;
typedef struct FRAMEHEADER {
unsigned int size; // velikost frame v bytech
unsigned short sign; // znacka frame OFAF1h
unsigned short actions; // pocet akci v tomto frame
char reserv [8]; // rezervovano
} frameheader;
typedef struct ACTIONHEADER {
unsigned int size; // velikost akce v bytech
unsigned short code; // kod akce
// 04h - predani casti nebo cele palety
// 07h - predavani zmenenych casti obrazu
// 0Dh - vymaze obrazovku
// 0Fh - cela obrazovka v RLE
// 10h - nekomprimovana kopie cele obrazovky
// nasleduji data akce
} actionheader;
FILE *flc;
flcheader h_flc;
frameheader h_frame;
actionheader h_action;
char frame_buffer [307205];
char *flc_buffer;
//unsigned int ladici;
void Open_FLC (char *filename);
void Close_FLC (void);
void Get_first_frame (void);
void Get_next_frame (void);
void Decompress_frame (void);
#endif

54
VIDEO/FLC/PLAY.C Normal file
View file

@ -0,0 +1,54 @@
#include <stdio.h>
#include <conio.h>
#include <graph.h>
#include <dos.h>
#include "flc.h"
#include "vesa.h"
void Set_TEXT_mode (void);
void main (int argc, char *argv[])
{
int x;
Open_FLC (argv[1]);
printf ("\nHlavicka FLC souboru %s:\n", argv[1]);
printf ("Delka celeho souboru: %d\n", h_flc.size);
printf ("Pocet frame: %d\n", h_flc.frames);
printf ("Velikost filmu: %dx%d\n", h_flc.width, h_flc.height);
printf ("Hloubka barvy: %d\n", h_flc.color);
// printf ("Rychlost prehravani: %d fps\n", 1000/h_flc.speed);
printf ("Offset prvniho frame: %d\n", h_flc.offset1);
getch ();
Set_VESA_mode (0x101);
delay (1000);
Get_first_frame ();
Decompress_frame ();
Show_screen (frame_buffer);
for (x=2; x<=h_flc.frames; x++)
{
Get_next_frame ();
Decompress_frame ();
Show_screen (frame_buffer);
delay (7);
}
getch ();
Set_TEXT_mode ();
Close_FLC ();
}
void Set_TEXT_mode (void)
{
union REGS inr, outr;
inr.h.ah = 0x00;
inr.h.al = 03;
int386 (0x10, &inr, &outr);
}

296
VIDEO/FLC/VESA.C Normal file
View file

@ -0,0 +1,296 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "vesa.h"
#include "dosmem.h"
extern void wm_ChangeBank_(int bank);
#pragma aux (ASM) wm_ChangeBank_;
void Set_VESA_mode (int mode)
{
union REGS r;
r.w.ax=0x4f02;
r.w.bx=mode;
int386 (0x10, &r, &r);
}
void Show_screen (char *display)
{
wm_ChangeBank_ (0);
memmove (0xa0000, display, 65536);
wm_ChangeBank_ (1);
memmove (0xa0000, (display+65536), 65536);
wm_ChangeBank_ (2);
memmove (0xa0000, (display+131072), 65536);
wm_ChangeBank_ (3);
memmove (0xa0000, (display+196608), 65536);
wm_ChangeBank_ (4);
memmove (0xa0000, (display+262144), 45056);
}
void Put_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
break;
};
}
}
void Get_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
break;
};
}
}
void Get_VESA_info (void)
{
char far *str;
VESA_INFO_BLOCK *p;
p=(VESA_INFO_BLOCK *)mem_alloc(sizeof(VESA_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS));
dpmiregs.EAX=0x00004f00;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaInfoBlock,str,sizeof(VESA_INFO_BLOCK));
mem_free(p);
if(dpmiregs.EAX!=0x4f)
{
printf ("VESA Bios extension not found!!!!");
exit (1);
}
}
void Get_mode_info (int mode)
{
char far *str;
VESA_MODE_INFO_BLOCK *p;
p=(VESA_MODE_INFO_BLOCK *)mem_alloc(sizeof(VESA_MODE_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS)); //nuluje registry
dpmiregs.EAX=0x00004f01;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
dpmiregs.ECX=mode;
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaModeInfoBlock,str,sizeof(VESA_INFO_BLOCK));
_VGAGran=VesaModeInfoBlock.WinGranularity;
mem_free(p);
}

70
VIDEO/FLC/VESA.H Normal file
View file

@ -0,0 +1,70 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#ifndef __VESA_H
#define __VESA_H
typedef struct
{ char VESASignature[4];
short VESAversion;
unsigned OEMStringPtr;
char capabilities[4];
short int *videomodeptr;
short int TotalMemory;
char dummy[236];
} VESA_INFO_BLOCK;
typedef struct
{ short unsigned ModeAttributes;
char WinAAttributes;
char WinBAttributes;
short unsigned WinGranularity;
short unsigned WinSize;
short unsigned WinASegment;
short unsigned WinBSegment;
short unsigned WinFuncPtroff;
short unsigned WinFuncPtrseg;
short unsigned BytesPerScanLine;
short unsigned XResolution;
short unsigned YResolution;
char Xcharsize;
char Ycharsize;
char NumberOfPlanes;
char BitsPerPixel;
char NumberOfBanks;
char MemoryModel;
char BankSize;
char NumberOfImagePages;
char Reserved;
char RedMaskSize;
char RedFieldPosition;
char GreenMaskSize;
char GreenFieldPosition;
char BlueMaskSize;
char BlueFieldPosition;
char RsvdMaskSize;
char DirectColorModeInfo;
char Dummy[216];
} VESA_MODE_INFO_BLOCK;
VESA_MODE_INFO_BLOCK VesaModeInfoBlock;
VESA_INFO_BLOCK VesaInfoBlock;
extern unsigned char _VGAPage=0;
extern unsigned char _VGAGran=0;
void Set_VESA_mode (int mode);
void Show_screen (char *display);
void Get_VESA_info (void);
void Get_mode_info (int mode);
void Put_image (int x, int y, int xlen, int ylen, char *image);
void Get_image (int x, int y, int xlen, int ylen, char *image);
#endif

63
VIDEO/FLC/VESA_.ASM Normal file
View file

@ -0,0 +1,63 @@
;EAX EDX EBX ECX
.386p
jumps
;############################################################################
; Constanty
;############################################################################
dlt_x equ 640
dlt_y equ 480
;############################################################################
; Datovy segment
;############################################################################
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
align 4
EXTRN __VGAPage:BYTE
EXTRN __VGAGran:BYTE
_DATA ENDS
DGROUP GROUP _DATA
;############################################################################
; Kodovy segment
;############################################################################
_TEXT SEGMENT PARA PUBLIC USE32 'CODE'
ASSUME cs:_TEXT, ds:_DATA
public wm_ChangeBank__
wm_ChangeBank__ PROC
push es
pushad
push eax
mov edx, eax
mov ebx, 0000h
mov eax, 4f05h
int 10h
pop eax
mov edx, eax
mov ebx, 0001h
mov eax, 4f05h
int 10h
popad
pop es
ret
wm_ChangeBank__ endp
;----------------------------------------------------------------------------
_TEXT ENDS
END

620
VIDEO/FLC2MGIF.C Normal file
View file

@ -0,0 +1,620 @@
// MOTION GIF - LZW komprimovana animace v rozliseni 320x180 256 barev avsak
// upravena pro prehravani v HICOLOR pro konkretni rezim (32768 barev)
// Format
/*
[ FRAME ] <pocet_chunku 1b><delka frame 3b>
[CHUNK] <cislo_akce 1b><delka_chunku 3b> !pozor delka je 3 bajtova (tj 16MB)
0 - PRADNY CHUNK
1 - LZW FULL SCREEN
2 - MGIF DELTA
3 - HICOLOR PALETE
4 - SOUND TRACK
5 - TEXT TRACK
6 - MGIF COPY
7 - SOUND INIT
Popis Chunku:
PRAZDNY_CHUNK - muze obsahovat soukrome informace
LZW_FULL_SCREEN
- ihned za hlavickou nasleduje LZW komprimovany obrazek
v rozliseni 320x180 256 barev
MGIF_DELTA
- cely blok je LZW komprimovany. Po dekomprimace blok obsahuje
dva druhy informaci. Prvni DWORD je ofset od pocatku dat
ktery ukazuje na zacatek graficke informace. Po tomto
DWORDU jsou ulozeny data o umisteni grafickych bodu v obrazu
Prvni byte znaci, kolik je nutne preskocit slov. (tj *2 byte)
Dalsi byte znaci, kolik je nutne zapsat slov (tj *2 byte)
Po tomto bytu je nutne prenest presne tolik slov z
grafickeho bloku na obrazovku. Dvojice bajtu se opakuji
dokud ani jeden z nich nema nejvyssi 2 bity nastavene.
Pak tento byte znaci ze uz na radce nic vic neni. Dolni cast
byte (tj 6 bitu) pak udava pocet radku, ktere je treba pre-
skocit. (nula=zadny).
HICOLOR PALETTE
- Prvni byte znamena pocet aktivnich barev. Pak nasleduje
paleta ve formatu xRRRRRGGGGGBBBBB. Rozdil oproti vsem
beznym paletam je v tom ze neni treba v palete udrzovat
barvy, ktere uz na obrazovce jsou, protoze zmena palety
se neprojevi na jiz zobrazenem obrazku.
SOUND_TRACK
- Kazdy frame obsahuje zvukovou stopu. Je to RAW format.
Pro verzi MGIF97 zde je zvukova informace ulozena ve
zvukove kvalite 16-bit stereo 22000Khz, ovsem komprimovana
na 50% jako MUS.
TEXT_TRACK
- Navic je ve mozne ve frame umistit textovou zpravu (titulek)
Prvni WORD udava dobu zobrazeni (pocet frame).
Pote nasleduje text zakoncen znakem 0;
MGIF_COPY - Za timto CHUNKEM je ulozen blok dat v nezakomprimovanem
tvaru(tj 57600byte);
*/
#include <stdio.h>
#include <stdlib.h>
#include <types.h>
#include <bgraph.h>
#include <memman.h>
#include <mem.h>
#include "flc.h"
#include "lzw.h"
#include <math.h>
#define MGIF "MGIF"
#define MGIF_Y "97"
#define VER 0x100
#define MGIF_EMPTY 0
#define MGIF_LZW 1
#define MGIF_DELTA 2
#define MGIF_PAL 3
#define MGIF_SOUND 4
#define MGIF_TEXT 5
#define MGIF_COPY 6
#define MGIF_SINIT 7
#define FRAME_X 320
#define FRAME_Y 180
#define FRAME_LEN (FRAME_X*FRAME_Y)
#define DELTA_LEN (3*FRAME_LEN)
#define LZW_LEN (2*FRAME_LEN)
#define SOUND_SPEED 44100
#define PRE_SOUND ((256*1024)/2)
#define ZTRATA lowq
#define BZTRATA colorq
#define MAX_FRAME max_fr
#define MIN_FRAME min_fr
short mult_table[64];
short square_table[4096];
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
word last_frame[FRAME_Y][FRAME_X];
char frame_delta[FRAME_LEN];
char delta_data[DELTA_LEN];
word color_state[32*32+32*32+32*32];
char calc_data[FRAME_LEN];
int delta_data_size;
int frame_delta_size;
int speed=20;
int last_frame_size;
int total_frames;
int lowq=0;
int colorq=0;
int max_fr=999999;
int min_fr=0;
int hranice;
int hdiff=0;
struct mgif_header gh;
char lzw_buffer[LZW_LEN];
char pal_use[256],color_map[256];
word hipal[256],max_colors;
FILE *mgf;
long of_pos;
int of_chunks;
void open_frame()
{
of_chunks=0;
of_pos=ftell(mgf);
fwrite(&of_pos,1,4,mgf);
}
void close_frame()
{
long fsize,p;
last_frame_size=fsize=(p=ftell(mgf))-of_pos-4;
fseek(mgf,of_pos,SEEK_SET);
fwrite(&of_chunks,1,1,mgf);
fwrite(&fsize,1,3,mgf);
fseek(mgf,p,SEEK_SET);
total_frames++;
}
void write_chunk(char action,long size,void *data)
{
fwrite(&action,1,1,mgf);
fwrite(&size,1,3,mgf);
fwrite(data,1,size,mgf);
of_chunks++;
}
void conv_2_hicolor()
{
int i,r,g,b;
for(i=0;i<256;i++)
{
r=(flc_paleta[i][0]>>3);
g=(flc_paleta[i][1]>>3);
b=(flc_paleta[i][2]>>3);
hipal[i]=((r<<10)+(g<<5)+b);
}
}
char find_color(word c); //najde barvu v palete a vraci byte
#pragma aux find_color parm [eax]=\
"mov edi,offset hipal"\
"mov ecx,256"\
"repne scasw"\
"mov eax,edi"\
"sub eax,offset hipal"\
"shr eax,1"\
"dec eax"\
value [al] modify[edi ecx];
void init_palmap()
{
int i;
memset(pal_use,0,sizeof(pal_use)); // nuluj pristupy k barvam
for(i=0;i<256;i++) color_map[i]=find_color(hipal[i]); //redukuj paletu;
max_colors=256; // pocet barev zatim 256;
}
char test_transp(char c,word w)
{
int r1,g1,b1;
int r2,g2,b2;
int diff;
r1=flc_paleta[c][0]>>3;
g1=flc_paleta[c][1]>>3;
b1=flc_paleta[c][2]>>3;
w&=0x7fff;
b2=w;g2=b2>>5;r2=g2>>5;b2&=0x1f;g2&=0x1f;
r1-=r2;g1-=g2;b1-=b2;
diff=abs(r1)+abs(g1<<1)+abs(b1);
return diff<=hranice;
}
void create_delta(char *frame_buffer)
{
char *delta;
char *data;
long colors2;
int x,y;
word *p;
char skip,skc,cpc;
char c1,c2,*a,d;
delta=delta_data;
data=frame_delta;
a=frame_buffer;
for(y=0;y<180;y++)
{
p=&last_frame[y];
skip=1;
skc=0;
cpc=0;
for(x=0;x<160;x++)
{
c1=*a++;c2=*a++;
c1=color_map[c1];
c2=color_map[c2];
d=test_transp(c1,p[0]) && test_transp(c2,p[1]);
if (d!=skip)
{
if (skip) *delta++=skc;else *delta++=cpc;
skip=!skip;skc=0;cpc=0;
}
if (!skip)
{
*data++=c1;
*data++=c2;
colors2=hipal[c1]+(hipal[c2]<<16);
*(long *)p=colors2;
cpc++;
}
else skc++;
p+=2;
pal_use[c1]=1;
pal_use[c2]=1;
}
if (!skip) *delta++=cpc;
if (skc==160 && *(delta-1)!=0xff && delta!=delta_data) delta[-1]++; //preskoc n radek
else *delta++=0xc0; //oznac konec radky
}
delta_data_size=delta-delta_data;
frame_delta_size=data-frame_delta;
}
void reduce_palette() //redukuje paletu na nejmensi nutny pocet barev
{
int i,j;
for(i=0,j=0;i<256;i++)
{
if (pal_use[i])
{
hipal[j]=hipal[i];
color_map[i]=j++;
}
}
max_colors=j;
}
void filter_colors(void *block,int size,void *colormap); //prefiltruje blok dat podle color_map
#pragma aux filter_colors parm [edi][ecx][ebx]=\
"lp1: mov al,[edi]"\
" xlatb"\
" stosb"\
" loop lp1"\
modify [eax];
void *join_two_blocks(void *d1,void *d2,int siz1,int siz2,long *celk)
{
long siz;
char *d;
void *x;
siz=siz1+siz2+4;
d=(char *)getmem(siz);
x=d;
memcpy(d,&siz1,4);d+=4;
memcpy(d,d1,siz1);d+=siz1;
memcpy(d,d2,siz2);
*celk=siz;
return x;
}
void create_last_frame(void *source,void *target,void *pal,int size);
#pragma aux create_last_frame parm [esi][edi][ebx][ecx]=\
"lp1: lodsb"\
" movzx eax,al"\
" mov eax,[eax*2+ebx]"\
" stosw"\
" loop lp1"\
modify[eax]
void create_mgif_pal()
{
write_chunk(MGIF_PAL,max_colors*2,hipal);
}
void create_mgif_lzw()
{
int siz;
conv_2_hicolor();
init_palmap();
create_mgif_pal();
filter_colors(frame_buffer,FRAME_LEN,color_map);
create_last_frame(frame_buffer,last_frame,hipal,FRAME_LEN);
init_lzw_compressor(8);
memset(lzw_buffer,0,sizeof(lzw_buffer));
siz=lzw_encode(frame_buffer,lzw_buffer,FRAME_LEN);
if (siz>FRAME_LEN) write_chunk(MGIF_COPY,FRAME_LEN,frame_buffer);
else write_chunk(MGIF_LZW,siz,lzw_buffer);
done_lzw_compressor(8);
}
void create_color_state()
{
int i;
int r1,g1,b1;
int r2,g2,b2;
int diff;
char *c;
word *w;
memset(color_state,0,sizeof(color_state));
c=frame_buffer;
w=last_frame;
for(i=0;i<FRAME_LEN;i++)
{
r1=flc_paleta[*c][0]>>3;
g1=flc_paleta[*c][1]>>3;
b1=flc_paleta[*c][2]>>3;
b2=*w;g2=b2>>5;r2=g2>>5;b2&=0x1f;g2&=0x1f;
r1-=r2;g1-=g2;b1-=b2;
diff=abs(r1)+abs(g1<<1)+abs(b1);
color_state[diff]++;
c++;w++;
}
}
void set_max_color_change(int cchange)
{
int i,s;
s=0;cchange=57600-cchange;
for(i=sizeof(color_state)/sizeof(word)-1;s<cchange && i>0;i--) s+=color_state[i];
if (s>=cchange) i++;
hranice=i+hdiff;if (hranice<0) hranice=0;
}
int rozptyl(int v1,int v2)
{
int c1,c2,x,s;
x=v1+v2>>1;
c1=(x-v1);
c2=(x-v2);
s=c1*c1+c2*c2;
return s;
}
void create_low_quality()
{
void *snd;int l;
char *sn,*sr,c1,c2;
int rs,bs,gs;
l=FRAME_LEN;
sr=frame_buffer;
snd=calc_data;
sn=(char *)snd;
l--;
while (l--)
{
c1=*sr++;
c2=*sr;
rs=rozptyl(flc_paleta[c1][0],flc_paleta[c2][0]);
gs=rozptyl(flc_paleta[c1][1],flc_paleta[c2][1]);
bs=rozptyl(flc_paleta[c1][2],flc_paleta[c2][2]);
if (rs+gs+bs<ZTRATA)
{
*sn++=c1;
*sn++=c1;
sr++;if(!l--) break;
}
else *sn++=c1;
}
create_delta(snd);
}
void create_mgif_delta()
{
void *d;
long siz;
conv_2_hicolor();
init_palmap();
if (BZTRATA) create_color_state();
set_max_color_change(BZTRATA);
create_low_quality();
if (delta_data_size+frame_delta_size>FRAME_LEN)
{
create_mgif_lzw();
return;
}
if (!frame_delta_size) return;
reduce_palette();
filter_colors(frame_delta,frame_delta_size,color_map);
d=join_two_blocks(delta_data,frame_delta,delta_data_size,frame_delta_size,&siz);
init_lzw_compressor(8);
memset(lzw_buffer,0,sizeof(lzw_buffer));
siz=lzw_encode(d,lzw_buffer,siz);
done_lzw_compressor();
free(d);
if (siz>FRAME_LEN)
{
create_mgif_lzw();
return;
}
create_mgif_pal();
write_chunk(MGIF_DELTA,siz,lzw_buffer);
}
void create_sound_track(int size)
{
void *p;
p=getmem(size);
memset(p,0,size);
write_chunk(MGIF_SOUND,size,p);
free(p);
}
void reserve_track()
{
int size;
size=SOUND_SPEED/speed;
size&=~1;
create_sound_track(size);
}
void prereserve_tracks()
{
int size;
int celk;
size=SOUND_SPEED/speed;
size&=~1;
celk=PRE_SOUND;
while (celk-size>0)
{
open_frame();
create_sound_track(size);
close_frame();
celk-=size;
}
if (celk)
{
open_frame();
create_sound_track(celk);
close_frame();
}
}
void fill_header(int frames)
{
memset(&gh,0,sizeof(gh));
strncpy(gh.sign,MGIF,4);
strncpy(gh.year,MGIF_Y,2);
gh.eof=26;
gh.ver=VER;
gh.frames=frames;
}
void show_screen()
{
word *c;
int i,j;
word *w;
c=last_frame;
w=screen;
for(i=0;i<180;i++)
{
for(j=0;j<320;j++)
{
*w++=*c;
*w++=*c;
c++;
}
w+=640;
}
showview(0,0,640,360);
showview(0,400,200,20);
}
void write_frame_size(int i,int col)
{
char s[20];
curcolor=0;bar(0,400,200,420);
sprintf(s,"%d %d %d",i,col,hranice);position(0,400);outtext(s);
}
compress_flc(char *name)
{
int x;
Open_FLC (name);
charcolors[0]=0;
charcolors[1]=0x7fff;
Get_first_frame ();
Decompress_frame ();
curcolor=0;bar(0,0,639,479);
open_frame();
create_mgif_lzw();
close_frame();write_frame_size(last_frame_size,max_colors);
show_screen();
for (x=2; x<=h_flc.frames; x++)
{
Get_next_frame ();
Decompress_frame ();
open_frame();
create_mgif_delta();
close_frame();
write_frame_size(last_frame_size,max_colors);
if (last_frame_size>MAX_FRAME) hdiff++;
else if (last_frame_size<MIN_FRAME && hranice>0) hdiff--;
else if (hdiff>0) hdiff--;else if(hdiff<0) hdiff++;
show_screen ();
}
Close_FLC();
}
void create_mgf_file(char *name)
{
mgf=fopen(name,"wb+");
fwrite(&gh,1,sizeof(gh),mgf);
total_frames=0;
}
void close_mgf_file()
{
fseek(mgf,0,SEEK_SET);
fill_header(total_frames);
fwrite(&gh,1,sizeof(gh),mgf);
fclose(mgf);
}
void create_mult_and_square()
{
int i;
puts("Creating tables...");
for(i=0;i<64;i++) mult_table[i]=(short)((i-32)*(i-32));
for(i=0;i<4096;i++) square_table[i]=(short)sqrt(i);
}
extern int sada7;
main(int argc,char *argv[])
{
puts("\n(C)1997 Komprimator Motion GIF v0.9 by Ondrej Novak");
if (argc<3)
{
puts("Pouziti:");putchar('\n');;
puts("FLCMGIF source.flc target.mgf");putchar('\n');
puts("Tento program generuje soubor MGF z originalniho FLC bez vkladani\n"
"prazdne zvukove stopy a bez ztratove kompresse (pouze convertor)");
exit(0);
}
create_mgf_file(argv[2]);
initmode32();
curfont=(void *)&sada7;
compress_flc(argv[1]);
closemode();
puts("Zaviram Motion GIF...");
close_mgf_file();
}

119
VIDEO/JPEGMGFA.ASM Normal file
View file

@ -0,0 +1,119 @@
.model small
.386
;16 bit line (de)comprimator
;
DGROUP group _DATA
extrn _cos_tab:word;
extrn _line_skip:dword
extrn _xlat_table:dword
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
ADDC macro REG1,REG2,CLIP
local addc1
add REG1,REG2
jno addc1
shl REG2,1
Mov REG2,CLIP
adc REG2,0
mov REG1,REG2
addc1:
endm
;cos_tab maji format:
; adresa = pqii (hex)
; p=pozice bodu (0-15 rozdeleno na yyxx)
; q=pozice harmonicke (0-15 je rozdeleno podle code_tabs)
; i=amplituda harmonicke(0-255);
;
; hodnoty jsou FIXED real (reprezentovane v short)
; vysledek je nutne podelit 32;
unpack_quant macro
local upqlp1
;ah - point
;vraci dh - bod
;cl - block_size
;esi - quant_list
lea ebx,_cos_tab;vem adresu _cos_tab
shl ah,4 ;presun pozici bodu do mista p
and eax,0xf000h ;odmaskuj zbytek
xor ebp,ebp ;vynuluj akumulator (ebp)
upqlp1: lodsb ;vem hodnotu harmonicke na pozici ii
add ebp,[ebx+eax*4];pricti k bp obsah v cos_tab
add eax,0100h ;zvys q
dec cl ;kontrola konce retezce
jnz upqlp1
sar ebp,9 ;vysledek podel 128 (32*4)
mov eax,ebp ;vysledek je v al
endm
public unpack_block_
unpack_block_: ;esi - data
;edi - out
;ecx - size
push ebp ;uchovej ebp
mov ch,cl ;uchovej velikost retezce v ch
mov dl,0 ;dl je pozice bodu
mov dh,16 ;dh je pocet bodu
upblck1:push esi ;uchovej esi
mov ah,dl ;napln ah pozici bodu
mov cl,ch ;napln cl delko
unpack_quant ;volej makro pro vypocet bodu
pop esi ;obnov esi
add [edi],al;zapis vysledny bod (vysetruj jako rozdil od predchoziho)
inc edi
inc dl ;presun se na dalsi pozici
dec dh ;sniz citac
jnz upblck1 ;opakuj
pop ebp ;obnov ebp
ret
public konv_iyg_hicolor_ ;esi - block i
;edx - block r+b
;ebx - block g+b
;edi - out(screen) (hicolor xRRRRRGGGGGBBBBB
konv_iyg_hicolor_:
push ebp
mov ebp,ebx
lea ebx,_xlat_table
mov cl,16 ;celkem ctverec 4x4
kiyglp1:mov ch,[esi] ;ch obsahuje intenzitu
mov al,ch ;zkopiruj ch do registru pro R G (ch je B)
mov ah,ch
sub ah,[edx] ;vypocet R (I-(R+B)) R+B=[ebp]
sub ch,[ds:ebp] ;vypocet G
sub al,ah ;vypocet B (I-R-G)
sub al,ch
xlatb
xchg ch,al
xlatb
xchg al,ah
xlatb
xchg al,ah
shl al,3 ;al<<3 000RRRRRGGGGG000 eax
shl eax,2 ;ax<<2 0RRRRRGGGGG00000 eax
or al,ch ;or ch 0RRRRRGGGGGBBBBB eax
stosw ;zapis dva body
stosw
inc esi ;zvys indexy do bufferu
inc edx
inc ebp
dec cl ;sniz citac
test cl,3 ;test na dolni 2 bity, pri 0 jdeme na dalsi radek
jnz kiyglp1
mov eax,_line_skip ;delka obrazovky
sub eax,16 ;odecti celkem 4*2*2=16 byte
add edi,eax ;pricti k ukazateli na obrazovku
or cl,cl ;test na cl==0
jnz kiyglp1 ;kdyz je pozitivni tak konec
pop ebp
ret
_TEXT ends
end

172
VIDEO/JPEGMGIF.C Normal file
View file

@ -0,0 +1,172 @@
#include <types.h>
#include <stdio.h>
#include <math.h>
#include "jpegmgif.h"
typedef short C_MATICE[4][4];
typedef float R_MATICE[4][4];
/*
C_MATICE quant=
{
{16,10,24,51},
{14,16,40,69},
{18,37,68,103},
{49,78,103,120},
};
*/
C_MATICE quant=
{
{2,2,4,24},
{2,4,8,26},
{4,8,50,80},
{8,30,80,88},
};
char xlat_table[256];
char code_tab[][2]=
{
{0,0},{1,0},{0,1},{0,2},{1,1},{2,0},{3,0},{2,1},{1,2},{0,3},{1,3},{2,2},{3,1},
{3,2},{2,3},{3,3}
};
int cos_tab[16][16][256];
short cuv_tab[16];
TBOX *rbbox;
TBOX *gbbox;
TBOX *ibox;
#define CUV (1/1.414)
#define PI 3.14159265
#define C(u) (u==0?CUV:1)
#define FIXED 512
#define SCAN_LINE 640
int line_skip=4*640;
void unpack_block(void *source,void *target,int size);
#pragma aux unpack_block parm [esi][edi][ecx] modify [ebx edx eax]
void konv_iyg_hicolor(void *ii,void *rb,void *gb,void *screen);
#pragma aux konv_iyg_hicolor parm[esi][edx][ebx][edi] modify [eax ecx]
void create_cos_tab()
{
char u,v,i,k,x,y;
int j,tst;
signed char cc,*c;
for(j=0;j<256;j++)
for(i=0;i<16;i++)
for(k=0;k<16;k++)
{
u=code_tab[i][0];
v=code_tab[i][1];
x=k & 3;
y=k >> 2;
cc=j & 0xff;
tst=cos_tab[k][i][j]=(int)(quant[u][v]*cc*C(u)*C(v)*cos((2*x+1)*u*PI/8.0)*cos((2*y+1)*v*PI/8.0)*FIXED);
}
for(i=0;i<16;i++)
{
u=code_tab[i][0];
v=code_tab[i][1];
cuv_tab[i]=(u==0)+(v==0);
}
c=xlat_table;
for(j=0;j<256;j++) if (j>127) *c++=0;else if(j>31) *c++=31;else *c++=j;
}
short zaokrouhlit(float f)
{
if (f>0) return (short)(f+0.5);
if (f<0) return (short)(f-0.5);
return 0;
}
void Dopredna_transformace(C_MATICE data,C_MATICE koef)
{
char u,v,x,y;
float msum;
for(u=0;u<4;u++)
for(v=0;v<4;v++)
{
msum=0;
for(x=0;x<4;x++)
for(y=0;y<4;y++)
msum+=data[x][y]*cos((2*x+1)*u*PI/8.0)*cos((2*y+1)*v*PI/8.0);
msum*=C(u)*C(v)/4.0;
koef[u][v]=zaokrouhlit(msum/quant[u][v]);
}
}
void Kodovani(C_MATICE data,char *out)
{
int i;
for(i=0;i<16;i++)
{
*out++=(char)(data[code_tab[i][0]][code_tab[i][1]]);
}
}
int string_size(char *data)
{
int i;
i=16;
do
i--;
while (i && !data[i]);
return i+1;
}
int transformace(void *screen_data,signed char *trans_data,int nextline,int box_place)
{
C_MATICE icm,rbcm,gbcm;
C_MATICE irm,rbrm,gbrm;
short i,r,g,a=0;
signed char *p;
signed char *ii,*rb,*gb;
int x,y;
char *tr=trans_data;
ii=ibox[box_place];
rb=rbbox[box_place];
gb=gbbox[box_place];
for(y=0;y<4;y++)
{
p=(char *)screen_data+nextline*3*y;
for(x=0;x<4;x++,a++)
{
i=(p[2]+p[1]+p[0]);
r=(i-p[0]);
g=(i-p[1]);
icm[x][y]=i-ii[a];
rbcm[x][y]=r-rb[a];
gbcm[x][y]=g-gb[a];
p+=3;
}
}
Dopredna_transformace(icm,irm);
Dopredna_transformace(rbcm,rbrm);
Dopredna_transformace(gbcm,gbrm);
Kodovani(irm,trans_data+1);trans_data+=1+(*trans_data=string_size(trans_data+1));
Kodovani(rbrm,trans_data+1);trans_data+=1+(*trans_data=string_size(trans_data+1));
Kodovani(gbrm,trans_data+1);trans_data+=1+(*trans_data=string_size(trans_data+1));
return trans_data-tr;
}
void zpetna_transformace(char **data,void *screen,int box_place)
{
TBOX *ii,*rb,*gb;
char *dd=*data;
unpack_block(dd+1,ii=ibox+box_place,*dd);dd+=dd[0]+1;
unpack_block(dd+1,rb=gbbox+box_place,*dd);dd+=dd[0]+1;
unpack_block(dd+1,gb=rbbox+box_place,*dd);dd+=dd[0]+1;
*data=dd;
konv_iyg_hicolor(ii,rb,gb,screen);
}

10
VIDEO/JPEGMGIF.H Normal file
View file

@ -0,0 +1,10 @@
void create_cos_tab();
int transformace(void *screen_data,char *trans_data,int nextline,int box_place0);
void zpetna_transformace(char **data,void *screen,int box_place);
typedef signed char TBOX[4][4];
extern TBOX *rbbox;
extern TBOX *gbbox;
extern TBOX *ibox;

252
VIDEO/JPEG_SIM.C Normal file
View file

@ -0,0 +1,252 @@
#include <types.h>
#include <stdio.h>
#include <math.h>
#include <bgraph.h>
#include <mem.h>
#include <conio.h>
#include "flc.h"
typedef short C_MATICE[8][8];
typedef float R_MATICE[8][8];
C_MATICE quant=
{
{16,11,10,16,24,40,51,61},
{12,12,14,19,26,58,60,55},
{14,13,16,24,40,57,69,56},
{14,17,22,29,51,87,80,61},
{18,22,37,56,68,109,103,77},
{24,35,55,64,81,104,113,92},
{49,64,78,87,103,121,120,101},
{72,92,95,98,112,100,103,99}
};
/*C_MATICE test=
{
{139,144,149,153,155,155,155,155},
{144,151,153,156,159,156,156,156},
{150,155,160,163,158,156,156,156},
{159,161,162,160,160,159,159,159},
{159,160,161,162,162,155,155,155},
{161,161,161,161,160,157,157,157},
{162,162,161,163,162,157,157,157},
{162,162,161,161,163,158,158,158}
};
*/
char code_tab[][2]=
{
{0,0},{1,0},{0,1},{0,2},{1,1},{2,0},{3,0},{2,1},{1,2},{0,3},{0,4},{1,3},{2,2},
{3,1},{4,0},{5,0},{4,1},{3,2},{2,3},{1,4},{0,5},{0,6},{1,5},{2,4},{3,3},{4,2},
{5,1},{6,0},{7,0},{6,1},{5,2},{4,3},{3,4},{2,5},{1,6},{0,7},{1,7},{2,6},{3,5},
{4,4},{5,3},{6,2},{7,1},{7,2},{6,3},{5,4},{4,5},{3,6},{2,7},{3,7},{4,6},{5,5},
{6,4},{7,3},{7,4},{6,5},{5,6},{4,7},{5,7},{6,6},{7,5},{7,6},{6,7},{7,7}
};
short cos_tab[64][64][256];
short cuv_tab[64];
#define CUV (1/1.414)
#define PI 3.14159265
#define C(u) (u==0?CUV:1)
#define FIXED 128
#define SCAN_LINE 640
char vystup[120000];
char frame[120000];
char *ip;
void create_cos_tab()
{
char u,v,i,k,x,y;
int j;
for(j=0;j<256;j++)
for(i=0;i<64;i++)
for(k=0;k<64;k++)
{
u=code_tab[i][0];
v=code_tab[i][1];
x=k & 0x7;
y=k>>3;
cos_tab[k][i][j]=(short)(quant[u][v]/2*(j-128)*cos((2*x+1)*u*PI/16)*cos((2*y+1)*v*PI/16)*FIXED/4);
}
for(i=0;i<64;i++)
{
u=code_tab[i][0];
v=code_tab[i][1];
cuv_tab[i]=(u==0)+(v==0);
}
}
void Dopredna_transformace(C_MATICE data,R_MATICE koef)
{
char u,v,x,y;
float msum;
for(u=0;u<8;u++)
for(v=0;v<8;v++)
{
msum=0;
for(x=0;x<8;x++)
for(y=0;y<8;y++)
msum+=data[x][y]*cos((2*x+1)*u*PI/16)*cos((2*y+1)*v*PI/16);
msum*=0.25*C(u)*C(v);
koef[u][v]=msum;
}
}
short zaokrouhlit(float f)
{
if (f>0) return (short)(f+0.5);
if (f<0) return (short)(f-0.5);
return 0;
}
void Kvantifikace(R_MATICE data,C_MATICE out)
{
char u,v;
for(u=0;u<8;u++)
for(v=0;v<8;v++)
out[u][v]=zaokrouhlit(data[u][v]*2/quant[u][v]);
}
void Kodovani(C_MATICE data,char *out)
{
int i;
for(i=0;i<64;i++)
{
*out++=(char)(data[code_tab[i][0]][code_tab[i][1]]);
}
}
void Zpetna_rychla_transformace(char *data,int delka,char *vystup)
{
char *hodn;
char *p;
char i,j;
int s;
p=vystup;
for(j=0;j<64;j++)
{
s=0;hodn=data;
for(i=0;i<delka;i++)
{
switch (cuv_tab[i])
{
case 0:s=s+cos_tab[j][i][*hodn++^0x80];break;
case 1:s=s+cos_tab[j][i][*hodn++^0x80]*(short)(FIXED*C(0))/FIXED;break;
case 2:s=s+cos_tab[j][i][*hodn++^0x80]>>1;break;
}
}
*p++=(char)(s/FIXED);
}
}
void read_bar_8x8(char *data,C_MATICE vystup)
{
int i,j;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
vystup[j][i]=*data++;
data+=SCAN_LINE-j;
}
}
void write_jpg_info(char *block,char *vystup,int *size)
{
for(*size=64;*size>0;(*size)--)
if (block[*size-1]!=0) break;
memcpy(vystup,size,1);
memcpy(vystup+1,block,*size);
}
void konvert_color_Y()
{
int i;
char *c,*d;
c=frame_buffer;
d=frame;
for(i=0;i<sizeof(frame);i++,c++) *d++=flc_paleta[*c][0]+flc_paleta[*c][1]+flc_paleta[*c][2]>>2;
}
void compress_layer(char *from,char *to)
{
R_MATICE r;
C_MATICE c;
char out[64];
int s,x,y;
for(y=0;y<24;y++)
for(x=0;x<80;x++)
{
read_bar_8x8(&from[(y*SCAN_LINE+x)*8],c);
Dopredna_transformace(c,r);
Kvantifikace(r,c);
Kodovani(c,out);
write_jpg_info(out,to,&s);
to+=s+1;
}
}
void decompress_layer(char *from,char *to)
{
char size;
int x,y,z;
char out[64];
char *a;
for(y=0;y<24;y++)
for(x=0;x<80;x++)
{
a=to+((SCAN_LINE*y+x)*8);
size=*from++;
Zpetna_rychla_transformace(from,size,out);
from+=size;
for(z=0;z<8;z++) memcpy(a+=640,out+z*8,8);
}
}
void display()
{
word *c;
char *z;
char d;
int i;
c=lbuffer;
z=frame;
for(i=0;i<640*180;i++)
{
d=*z++;d>>=3;
*c++=d+(d<<5)+(d<<10);
}
}
void main()
{
printf("creating %d Kb table\n",sizeof(cos_tab)/1024);
create_cos_tab();
Open_FLC("trava.flc");
Get_first_frame();
Decompress_frame();
Close_FLC();
konvert_color_Y();
puts("compress");
compress_layer(frame,vystup);
puts("decompress");
decompress_layer(vystup,frame);
initmode32(NULL);
display();
getche();
closemode();
}

225
VIDEO/LZW.C Normal file
View file

@ -0,0 +1,225 @@
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <memman.h>
#define LZW_MAX_CODES 4096
typedef struct double_s
{
short group,chr,first,next;
}DOUBLE_S;
typedef DOUBLE_S CODE_TABLE[LZW_MAX_CODES];
DOUBLE_S *compress_dic;
int clear_code;
int end_code;
int free_code;
int nextgroup;
int bitsize,init_bitsize;
char old_value=0;
void do_clear_code()
{
int i;
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
for(i=0;i<clear_code;i++)
{
DOUBLE_S *p;
p=&compress_dic[i];
p->group=i;p->chr=-1;p->next=-1;p->first=-1;
}
}
void reinit_lzw()
{
do_clear_code();
}
void init_lzw_compressor(int dic_size)
{
compress_dic=(CODE_TABLE *)getmem(sizeof(CODE_TABLE));
clear_code=1<<dic_size;
end_code=clear_code+1;
free_code=end_code+1;
nextgroup=free_code;
init_bitsize=bitsize=dic_size+1;
do_clear_code();
}
void done_lzw_compressor()
{
free(compress_dic);
}
long output_code(void *target,long bitepos,int bitsize,int data);
#pragma aux output_code parm [edi][edx][ebx][eax]=\
"mov ecx,edx"\
"shr ecx,3"\
"add edi,ecx"\
"mov ecx,edx"\
"and cl,7h"\
"shl eax,cl"\
"or [edi],eax"\
"add edx,ebx"\
value[edx] modify [ecx];
int input_code(void *source,long *bitepos,int bitsize,int mask);
#pragma aux input_code parm [esi][edi][ebx][edx]=\
"mov ecx,[edi]"\
"mov eax,ecx"\
"shr eax,3"\
"mov eax,[esi+eax]"\
"and cl,7"\
"shr eax,cl"\
"and eax,edx"\
"add [edi],ebx"\
value[eax] modify [ecx];
int find_code(DOUBLE_S *p)
{
int ps;
ps=p->group;
ps=compress_dic[ps].first;
while (ps!=-1)
{
if (compress_dic[ps].chr==p->chr) return ps;
ps=compress_dic[ps].next;
}
return -1;
}
void add_code(DOUBLE_S *p)
{
p->first=-1;p->next=compress_dic[p->group].first;
memcpy(&compress_dic[nextgroup],p,sizeof(DOUBLE_S));
compress_dic[p->group].first=nextgroup;
nextgroup++;
}
long lzw_encode(char *source,void *target,int size)
{
long bitpos=0;
DOUBLE_S p;
int f;
clear:
old_value=p.group=*source++;size--;
while (size-->0)
{
p.chr=(int)((char)(*source++-old_value));old_value+=p.chr;
f=find_code(&p);
if (f<0)
{
bitpos=output_code(target,bitpos,bitsize,p.group);
add_code(&p);
if (nextgroup==(1<<bitsize)) bitsize++;
p.group=p.chr;
if (nextgroup>=LZW_MAX_CODES)
{
bitpos=output_code(target,bitpos,bitsize,p.group);
bitpos=output_code(target,bitpos,bitsize,clear_code);
do_clear_code();
goto clear;
}
}
else
p.group=f;
}
bitpos=output_code(target,bitpos,bitsize,p.group);
bitpos=output_code(target,bitpos,bitsize,end_code);
return (bitpos+8)>>3;
}
void de_add_code(DOUBLE_S *p,int *mask)
{
DOUBLE_S *q;
q=&compress_dic[nextgroup];q->group=p->group;q->chr=p->chr;q->first=compress_dic[p->group].first+1;
nextgroup++;
if (nextgroup==*mask)
{
*mask=(*mask<<1)+1;
bitsize++;
}
}
int expand_code(int code,char **target)
{
static int first;
if (code>end_code)
{
expand_code(compress_dic[code].group,target);
**target=old_value=compress_dic[code].chr+old_value;
(*target)++;
}
else
{
**target=old_value=code+old_value;
(*target)++;
first=code;
}
return first;
}
char fast_expand_code(int code,char **target);
#pragma aux fast_expand_code parm[eax][edi] modify [esi ecx] value [bl]
void lzw_decode(void *source,char *target)
{
long bitpos=0;
int code,old,i;
DOUBLE_S p;
int old_first;
int mask=0xff;
for(i=0;i<LZW_MAX_CODES;i++) compress_dic[i].first=0;
clear:
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
mask=(1<<bitsize)-1;
code=input_code(source,&bitpos,bitsize,mask);
old_first=fast_expand_code(code,&target);
old=code;
while ((code=input_code(source,&bitpos,bitsize,mask))!=end_code)
{
if (code==clear_code)
{
goto clear;
}
else if (code<nextgroup)
{
old_first=fast_expand_code(code,&target);
p.group=old;
p.chr=old_first;
de_add_code(&p,&mask);
old=code;
}
else
{
p.group=old;
p.chr=old_first;
de_add_code(&p,&mask);
old_first=fast_expand_code(code,&target);
old=code;
}
}
}

5
VIDEO/LZW.H Normal file
View file

@ -0,0 +1,5 @@
void init_lzw_compressor(int dic_size);
void done_lzw_compressor();
long lzw_encode(char *source,void *target,int size);
void lzw_decode(void *source,char *target);
void reinit_lzw();

55
VIDEO/LZWA.ASM Normal file
View file

@ -0,0 +1,55 @@
.model small
.386
;16 bit line (de)comprimator
;
DGROUP group _DATA
extern _old_value:byte
extern _compress_dic:dword
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
public fast_expand_code_
fast_expand_code_:
cmp eax,256
jnc expand
mov esi,[edi]
inc dword ptr [edi]
mov bl,al
add al,_old_value
mov [esi],al
mov _old_value,al
ret
expand:
mov ebx,_compress_dic
lea ecx,[eax*8+ebx]
movzx eax,word ptr [ecx+4]
add [edi],eax
push eax
mov esi,[edi]
eloop:movzx eax,word ptr [ecx+2]
mov [esi],al
dec esi
movzx eax,word ptr [ecx]
lea ecx,[eax*8+ebx]
cmp eax,256
jnc eloop
mov bl,al
add al,_old_value
mov [esi],al
inc dword ptr [edi]
pop ecx
elp2:inc esi
add al,[esi]
mov [esi],al
dec ecx
jnz elp2
mov _old_value,al
ret
_TEXT ends
end

261
VIDEO/LZWC.C Normal file
View file

@ -0,0 +1,261 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#define getmem(s) malloc(s)
#define New(typ) (typ *)getmem(sizeof(typ))
#define NewArr(typ,pocet) (typ *)getmem(sizeof(typ)*pocet);
#define ClrArr(p,typ,pocet) memset(p,0,sizeof(typ)*pocet);
#define LZW_MAX_CODES 4096
typedef struct double_s
{
short group,chr,first,next;
}DOUBLE_S;
typedef DOUBLE_S CODE_TABLE[LZW_MAX_CODES];
DOUBLE_S *compress_dic;
int clear_code;
int end_code;
int free_code;
int nextgroup;
int bitsize,init_bitsize;
char old_value=0;
void do_clear_code() //funkce maze slovni (clear code)
{
int i;
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
for(i=0;i<clear_code;i++)
{
DOUBLE_S *p;
p=&compress_dic[i];
p->group=i;p->chr=-1;p->next=-1;p->first=-1;
}
}
void reinit_lzw()
{
do_clear_code();
}
void init_lzw_compressor(int dic_size)
//dic size je velikost slovniku(bitova)
//pro 8 bitove hodnoty zde vloz 8.
{
compress_dic=(CODE_TABLE *)getmem(sizeof(CODE_TABLE));
clear_code=1<<dic_size;
end_code=clear_code+1;
free_code=end_code+1;
nextgroup=free_code;
init_bitsize=bitsize=dic_size+1;
do_clear_code();
}
void done_lzw_compressor()
{
free(compress_dic);
}
/*
long output_code(void *target,long bitepos,int bitsize,int data);
#pragma aux output_code parm [edi][edx][ebx][eax]=\
"mov ecx,edx"\
"shr ecx,3"\
"add edi,ecx"\
"mov ecx,edx"\
"and cl,7h"\
"shl eax,cl"\
"or [edi],eax"\
"add edx,ebx"\
value[edx] modify [ecx];
*/
long output_code_c(void *target,long bitepos,int bitesize,int data)
{
unsigned max_faces *c;
c=target;
c+=bitepos>>3;
data<<=bitepos & 7;
c[0]|=data;
c[1]=data>>8;
c[2]=data>>16;
return bitepos+bitesize;
}
int input_code(void *source,long *bitepos,int bitsize,int mask);
#pragma aux input_code parm [esi][edi][ebx][edx]=\
"mov ecx,[edi]"\
"mov eax,ecx"\
"shr eax,3"\
"mov eax,[esi+eax]"\
"and cl,7"\
"shr eax,cl"\
"and eax,edx"\
"add [edi],ebx"\
value[eax] modify [ecx];
int input_code_c(unsigned char *source,long *bitepos,int bitsize,int mask)
{
unsigned char *c;int x;
c=source;
c+=*bitepos>>3;
x=c[0]+(c[1]<<8)+(c[2]<<16);
x>>=*bitepos & 7;
x &= mask;
*bitepos=*bitepos+bitsize;
return x;
}
int find_code(DOUBLE_S *p)
//hleda skupinu ve slovniku. Pokud neexistuje vraci -1;
{
int ps;
ps=p->group;
ps=compress_dic[ps].first;
while (ps!=-1)
{
if (compress_dic[ps].chr==p->chr) return ps;
ps=compress_dic[ps].next;
}
return -1;
}
void add_code(DOUBLE_S *p)
//vklada novou dvojici
{
p->first=-1;p->next=compress_dic[p->group].first;
memcpy(&compress_dic[nextgroup],p,sizeof(DOUBLE_S));
compress_dic[p->group].first=nextgroup;
nextgroup++;
}
long lzw_encode(unsigned char *source,void *target,int size)
//Encode LZW. zdroj, cil a velikost dat. Vraci velikost komprimovano.
{
long bitpos=0;
DOUBLE_S p;
int f;
clear:
old_value=p.group=*source++;size--;
while (size-->0)
{
p.chr=(int)((unsigned char)(*source++));old_value+=p.chr;
f=find_code(&p);
if (f<0)
{
bitpos=output_code_c(target,bitpos,bitsize,p.group);
add_code(&p);
if (nextgroup==(1<<bitsize)) bitsize++;
p.group=p.chr;
if (nextgroup>=LZW_MAX_CODES)
{
bitpos=output_code_c(target,bitpos,bitsize,p.group);
bitpos=output_code_c(target,bitpos,bitsize,clear_code);
do_clear_code();
goto clear;
}
}
else
p.group=f;
}
bitpos=output_code_c(target,bitpos,bitsize,p.group);
bitpos=output_code_c(target,bitpos,bitsize,end_code);
return (bitpos+8)>>3;
}
void de_add_code(DOUBLE_S *p,int *mask)
{
DOUBLE_S *q;
q=&compress_dic[nextgroup];q->group=p->group;q->chr=p->chr;q->first=compress_dic[p->group].first+1;
nextgroup++;
if (nextgroup==*mask)
{
*mask=(*mask<<1)+1;
bitsize++;
}
}
int expand_code(int code,unsigned char **target)
{
static int first;
if (code>end_code)
{
assert(compress_dic[code].group<code);
expand_code(compress_dic[code].group,target);
**target=old_value=compress_dic[code].chr;
(*target)++;
}
else
{
**target=old_value=code;
(*target)++;
first=code;
}
return first;
}
/*
char fast_expand_code(int code,char **target);
#pragma aux fast_expand_code parm[eax][edi] modify [esi ecx] value [bl]
*/
void lzw_decode(void *source,unsigned char *target)
//dekomprimuje lzw. Nevraci velikost, tu si musi program zajistit sam.
{
long bitpos=0;
int code,old,i;
DOUBLE_S p;
int old_first;
int mask=0xff;
for(i=0;i<LZW_MAX_CODES;i++) compress_dic[i].first=0;
clear:
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
mask=(1<<bitsize)-1;
code=input_code_c(source,&bitpos,bitsize,mask);
old_first=expand_code(code,&target);
old=code;
while ((code=input_code_c(source,&bitpos,bitsize,mask))!=end_code)
{
if (code==clear_code)
{
goto clear;
}
else if (code<nextgroup)
{
old_first=expand_code(code,&target);
p.group=old;
p.chr=old_first;
de_add_code(&p,&mask);
old=code;
}
else
{
p.group=old;
p.chr=old_first;
de_add_code(&p,&mask);
old_first=expand_code(code,&target);
old=code;
}
}
}

92
VIDEO/LZW_EX.C Normal file
View file

@ -0,0 +1,92 @@
#include "lzw.h"
#include "lzwc.c" //include nahrazuje MAK soubor.
#include <stdio.h>
#define MAX_BUFF 65536
#define INPUT "testx"
#define OUTPUT "testx.l"
#define ARCH "e:\\SYSLOG.LZW"
char input_buffer[MAX_BUFF*2];
char output_buffer[MAX_BUFF*2];
FILE *in,*out;
int datasize;
int compsize;
void open_files(char *sr,char *tg)
{
in=fopen(sr,"rb");
out=fopen(tg,"wb");
if (in==NULL || out==NULL) abort();
}
void close_files()
{
fclose(in);
fclose(out);
}
void read_normal()
{
datasize=fread(input_buffer,1,MAX_BUFF,in);
}
void save_normal()
{
fwrite(output_buffer,1,datasize,out);
}
int read_comp()
{
fread(&datasize,1,sizeof(datasize),in);
fread(&compsize,1,sizeof(datasize),in);
return fread(input_buffer,1,compsize,in);
}
void save_comp()
{
fwrite(&datasize,1,sizeof(datasize),out);
fwrite(&compsize,1,sizeof(datasize),out);
fwrite(output_buffer,1,compsize,out);
}
main()
{
puts("");
init_lzw_compressor(8);
open_files(INPUT,ARCH);
read_normal();
while (datasize!=0)
{
memset(output_buffer,0,sizeof(output_buffer));
compsize=lzw_encode(input_buffer,output_buffer,datasize);
printf("Origin: %d Packed: %d Ratio %d%%\n",datasize,compsize,compsize*100/datasize);
save_comp();
read_normal();
reinit_lzw();
}
close_files();
done_lzw_compressor();
init_lzw_compressor(8);
open_files(ARCH,OUTPUT);
while (read_comp())
{
lzw_decode(input_buffer,output_buffer);
save_normal();
reinit_lzw();
}
done_lzw_compressor();
printf("Compressed file has been extracted back\n");
close_files();
printf("and saved as %s.\n",OUTPUT);
}

500
VIDEO/MGFPLAYA.ASM Normal file
View file

@ -0,0 +1,500 @@
.model small
.386
;16 bit line (de)comprimator
;
DGROUP group _DATA
extrn _lbuffer:dword
extrn _backsndbuff:word
extrn _vals_save:dword
extrn _backsnd:dword
extrn _lastbank:dword
extrn _gr_page_end:word
extrn _gr_end_screen:dword
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
extrn mapvesaadr_:proc
extrn switchmap_:proc
extrn switchvesabank_:proc
public show_full_interl_lfb_
show_full_interl_lfb_:
;edi - target
;esi - source
;ebx - palette
push ebp
mov dl,180
shfif2: mov ecx,320
shfif1: lodsb
movzx eax,al
movzx eax,word ptr [eax*2+ebx]
mov ebp,eax
shl eax,16
or eax,ebp
stosd
dec ecx
jnz shfif1
add edi,1280
dec dl
jnz shfif2
pop ebp
ret
public show_delta_interl_lfb_
show_delta_interl_lfb_:
;edi - target
;esi - source
;ebx - palette
push ebp ;uchovej ebp
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdif6: push edi ;uloz adresu radku
shdif2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdif3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*8+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
shdif1: lodsb ;vem bajt z datove oblasti
movzx eax,al ;expanduj do eax
movzx eax,word ptr[eax*2+ebx] ;expanduj hicolor barvu
mov ebp,eax ;rozdvoj barvy
shl ebp,16
or eax,ebp
stosd ;zapis dva body
lodsb ;opakuj pro dalsi bod jeste jednou
movzx eax,al
movzx eax,word ptr[eax*2+ebx]
mov ebp,eax
shl ebp,16
or eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdif1 ;dokud neni 0
jmp shdif2 ;pokracuj _skip_ hodnotou
shdif3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz shdif4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,1280*2 ;preskoc radek
dec cl ;odecti citac radku
jnz shdif6 ;skok pokud neni konec
pop ebp
ret ;navrat
shdif4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdif5 ;je-li nula tak konec
shdif7: add edi,1280*2 ;preskoc radek
dec ch ;odecti ch
jnz shdif7 ;preskakuj dokud neni 0
jmp shdif6 ;cti dalsi _skip_
shdif5: pop ebp
ret ;konec
public show_full_interl_lfb130_
show_full_interl_lfb130_:
;edi - target
;esi - source
;ebx - palette
push ebp
mov dl,180
shfil2: mov ecx,160
shfil1: lodsw
movzx ebp,al
movzx ebp,word ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,word ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
stosd
dec ecx
jnz shfil1
add edi,640
dec dl
jnz shfil2
pop ebp
ret
public show_delta_interl_lfb130_
show_delta_interl_lfb130_:
;edi - target
;esi - source
;ebx - palette
push ebp ;uchovej ebp
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdil6: push edi ;uloz adresu radku
shdil2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdil3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*4+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
shdil1: lodsw
movzx ebp,al
movzx ebp,word ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,word ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdil1 ;dokud neni 0
jmp shdil2 ;pokracuj _skip_ hodnotou
shdil3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz shdil4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,1280 ;preskoc radek
dec cl ;odecti citac radku
jnz shdil6 ;skok pokud neni konec
pop ebp
ret ;navrat
shdil4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdil5 ;je-li nula tak konec
shdil7: add edi,1280 ;preskoc radek
dec ch ;odecti ch
jnz shdil7 ;preskakuj dokud neni 0
jmp shdil6 ;cti dalsi _skip_
shdil5: pop ebp
ret ;konec
public show_full_lfb12e_
show_full_lfb12e_:
;edi - target
;esi - source
;ebx - palette
push ebp
mov dl,180
shfl2: mov ecx,160
shfl1: lodsw
movzx ebp,al
movzx ebp,word ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,word ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
stosd
dec ecx
jnz shfl1
dec dl
jnz shfl2
pop ebp
ret
public show_delta_lfb12e_
show_delta_lfb12e_:
;edi - target
;esi - source
;ebx - palette
push ebp ;uchovej ebp
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdl6: push edi ;uloz adresu radku
shdl2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdl3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*4+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
shdl1: lodsw
movzx ebp,al
movzx ebp,word ptr ds:[ebp*2+ebx]
movzx eax,ah
movzx eax,word ptr ds:[eax*2+ebx]
shl eax,16
or eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdl1 ;dokud neni 0
jmp shdl2 ;pokracuj _skip_ hodnotou
shdl3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz shdl4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,640 ;preskoc radek
dec cl ;odecti citac radku
jnz shdl6 ;skok pokud neni konec
pop ebp
ret ;navrat
shdl4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdl5 ;je-li nula tak konec
shdl7: add edi,640 ;preskoc radek
dec ch ;odecti ch
jnz shdl7 ;preskakuj dokud neni 0
jmp shdl6 ;cti dalsi _skip_
shdl5: pop ebp
ret ;konec
nextbank macro
mov eax,_lastbank ;ano, pak vem cislo banky
inc eax ;pricti 1
mov _lastbank,eax ;zapis jako nove cislo banky
pushad ;uchovej vse
call switchvesabank_ ;prepni banku
popad ;obnov vse
movzx edi,di
add edi,0a0000h ;vynuluj dolni cast di
endm
skipm macro reg
local skp1
mov ax,_gr_page_end
movzx edi,di
dec ax
add edi,reg
inc eax
cmp edi,eax
jc skp1
mov eax,_lastbank ;ano, pak vem cislo banky
inc eax ;pricti 1
mov _lastbank,eax ;zapis jako nove cislo banky
pushad ;uchovej vse
call switchvesabank_ ;prepni banku
popad ;obnov vse
movzx edi,di
skp1: or edi,0a0000h
endm
public show_full_interl_bank_
show_full_interl_bank_:
;edi - target
;esi - source
;ebx - palette
call mapvesaadr_
mov dl,180
shfib2: mov ecx,320
push ebp
shfib1: cmp edi,_gr_end_screen
jc shfib3
nextbank
shfib3: lodsb
movzx eax,al
movzx eax,word ptr [eax*2+ebx]
mov ebp,eax
shl eax,16
or eax,ebp
stosd
dec ecx
jnz shfib1
pop ebp
add edi,1280
dec dl
jnz shfib2
ret
public show_delta_interl_bank_
show_delta_interl_bank_:
;edi - target
;esi - source
;ebx - palette
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
shdib6: push ebp ;uchovej ebp
push edi
call mapvesaadr_
shdib2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz shdib3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*8+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
cmp edi,_gr_end_screen
jc shdib1
nextbank
shdib1: lodsb ;vem bajt z datove oblasti
movzx eax,al ;expanduj do eax
movzx eax,word ptr[eax*2+ebx] ;expanduj hicolor barvu
mov ebp,eax ;rozdvoj barvy
shl ebp,16
or eax,ebp
stosd ;zapis dva body
cmp edi,_gr_end_screen
jc shdib8
nextbank
shdib8: lodsb ;opakuj pro dalsi bod jeste jednou
movzx eax,al
movzx eax,word ptr[eax*2+ebx]
mov ebp,eax
shl ebp,16
or eax,ebp
stosd
dec ch ;odecti _copy_ hodnotu
jnz shdib1 ;dokud neni 0
jmp shdib2 ;pokracuj _skip_ hodnotou
shdib3: pop edi
pop ebp
and ch,3fh ;odmaskuj hodni 2 bity
jnz shdib4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,2*1280
dec cl ;odecti citac radku
jnz shdib6 ;skok pokud neni konec
ret ;navrat
shdib4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz shdib5 ;je-li nula tak konec
shdib7: add edi,2*1280 ;preskoc radek
dec ch ;odecti ch
jnz shdib7 ;preskakuj dokud neni 0
jmp shdib6 ;cti dalsi _skip_
shdib5: ret ;konec
public sound_decompress_ ;dekompresuje hudbu
sound_decompress_: ;esi - source
;edi - target pos in backsndbuff
;ecx - datasize
;ebx - ampl_table
;(vraci edi - pozici v backsndbuff)
mov edx,_vals_save
snddec1:lodsb
movzx eax,al
movzx eax,word ptr [eax*2+ebx]
add dx,ax
mov _backsndbuff[edi],dx
add edi,2
and edi,3ffffh
rol edx,16
dec ecx
jnz snddec1
mov _vals_save,edx
ret
public test_next_frame_ ;testuje zda je volno pro dalsi zvukovy blok
test_next_frame_: ;edi - pozice
;ecx - delka bloku
mov ebx,_backsnd
shl ecx,1
shl ebx,2
xor ecx,3ffffh
sub edi,ebx
jnc tnf1
add edi,40000h
tnf1: cmp ecx,edi
rcl al,1
and al,1
ret
public show_full_interl_lfb_256_
show_full_interl_lfb_256_:
;edi - target
;esi - source
;ebx - palette
mov dl,180
s2fif2: mov ecx,320
s2fif1: lodsb
movzx eax,al
movzx eax,word ptr [eax*2+ebx]
stosw
dec ecx
jnz s2fif1
add edi,640
dec dl
jnz s2fif2
ret
public show_delta_interl_lfb_256_
show_delta_interl_lfb_256_:
;edi - target
;esi - source
;ebx - palette
push ebp ;uchovej ebp
mov cl,180 ;cl pocet zbyvajicich radek
add esi,4 ;preskoc ukazatel
mov edx,esi ;edx - zacatek delta mapy
add esi,[esi-4] ;esi - zacatek dat
s2dif6: push edi ;uloz adresu radku
s2dif2: mov ch,[edx] ;cti _skip_ hodnotu
mov al,ch
inc edx
or al,03fh ;test zda jsou 2 nejvyssi bity nastaveny
inc al
jz s2dif3 ;ano - preskakovani radku
movzx eax,ch ;expanduj _skip_ hodnotu do eax
lea edi,[eax*4+edi] ;vypocti novou pozici na obrazovce
mov ch,[edx] ;cti _copy_ hodnotu
inc edx
s2dif1: lodsb ;vem bajt z datove oblasti
movzx eax,al ;expanduj do eax
movzx eax,word ptr[eax*2+ebx] ;expanduj hicolor barvu
mov ebp,eax ;rozdvoj barvy
lodsb ;opakuj pro dalsi bod jeste jednou
movzx eax,al
movzx eax,word ptr[eax*2+ebx]
shl eax,16
or eax,ebp
stosd ;zapis 4 body
dec ch ;odecti _copy_ hodnotu
jnz s2dif1 ;dokud neni 0
jmp s2dif2 ;pokracuj _skip_ hodnotou
s2dif3: and ch,3fh ;odmaskuj hodni 2 bity
pop edi ;obnov edi
jnz s2dif4 ;pokud je ch=0 preskoc jen jeden radek;
add edi,640*2 ;preskoc radek
dec cl ;odecti citac radku
jnz s2dif6 ;skok pokud neni konec
pop ebp
ret ;navrat
s2dif4: inc ch ;pocet radek je ch+1
sub cl,ch ;odecti ch od zbyvajicich radek
jz s2dif5 ;je-li nula tak konec
s2dif7: add edi,640*2 ;preskoc radek
dec ch ;odecti ch
jnz s2dif7 ;preskakuj dokud neni 0
jmp s2dif6 ;cti dalsi _skip_
s2dif5: pop ebp
ret ;konec
_TEXT ends
end

558
VIDEO/MGFSOUND.C Normal file
View file

@ -0,0 +1,558 @@
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <mem.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <fcntl.h>
#include <io.h>
#include <wav.c>
#define BLK_SIZE 100000
#define CHANNELS 256
#define SND_NAME ".SNF"
typedef struct volstruc
{
int volslow,volsmax;
int volume;
int volume_end;
int vls;
}TVOLSTRUC;
typedef struct tchaninfo
{
FILE *snd;
char chans;
char bit8;
long repstart;
long id ;
long size;
TVOLSTRUC left,right;
}TCHANINFO;
TCHANINFO chaninfo[CHANNELS];
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
struct mgif_header gh;
short ampl_table[256];
signed short source[BLK_SIZE];
char target[BLK_SIZE];
int glob_volume=256;
long sfreq;
unsigned short chans;
FILE *sf;
int tf;
char *nsource;
char *ntarget;
long ssize;
long rsize,blck;
char difftype=4;
int last_channel;
long next_frame;
int find_free_channel()
{
int i;
for(i=0;i<256;i++) if (chaninfo[i].snd==NULL) return i;
printf("Nemohu pridat zvuk. Jiz je zaplneno vsech %d kanal\n",CHANNELS);
return -1;
}
void Create_table_16()
{
int a,c,d,e;
float b;
d=-1;e=0;
for(a=0;a<128;a++)
{
b=(a/128.0);
switch (difftype)
{
case 1:b=(b*32768.0);break;
case 2:b=(b*b*32768.0);break;
case 3:b=(b*b*b*32768.0);break;
case 4:b=(b*b*b*b*32768.0);break;
case 5:b=(b*b*b*b*b*32768.0);break;
}
c=(int)b;
if (c==d) e++;
d=c;c+=e;
ampl_table[128+a]=c;
ampl_table[128-a]=-c;
}
}
int find_index(int value)
{
int i;
if (value==0) return 128;
if (value>0)
{
for(i=128;i<256;i++)
if (ampl_table[i]>value) return i-1;
return 255;
}
else
{
for(i=128;i>=0;i--)
if (ampl_table[i]<value) return i+1;
return 1;
}
}
void compress_buffer_stereo(int size)
{
int i;
static int last1=0;
static int last2=0;
int val;
char indx;
for(i=0;i<size;i++)
{
if (i & 1)
{
val=source[i];
indx=find_index(val-last1);
last1+=ampl_table[indx];
if (last1>32768 || last1<-32768) abort();
target[i]=indx;
}
else
{
val=source[i];
indx=find_index(val-last2);
last2+=ampl_table[indx];
if (last2>32768 || last2<-32768) abort();
target[i]=indx;
}
}
}
void find_data()
{
char w[5]="data";
int i,d;
i=0;
do
{
d=fgetc(sf);
if (d==w[i]) i++;else i=0;
if (d==EOF) abort();
}
while (i<4);
}
void open_wav(char *wav)
{
TCHANINFO *inf;
int i;
struct t_wave *wavinf;
FILE *snd;
i=find_free_channel();
if (i==-1) return;
last_channel=i;
inf=chaninfo+i;
snd=fopen(wav,"rb");
if (snd==NULL)
{
printf("Soubor %s neexistuje.\n",wav);
return;
}
if (find_chunk(snd,WAV_FMT)==-1)
{
printf("Soubor %s ma poskozenou hlavicku\n",wav);
fclose(snd);
return;
}
wavinf=(struct t_wave *)malloc(get_chunk_size(snd));
if (wavinf==NULL)
{
puts("Nedostatek pamˆti.");
return;
}
read_chunk(snd,wavinf);
if (wavinf->wav_mode!=1)
{
printf("Tento program podporuje pouze WAVy typu 1 (%s)\n",wav);
free(wavinf);
fclose(snd);
return;
}
inf->chans=wavinf->chans;
inf->bit8=wavinf->freq*wavinf->chans==wavinf->bps;
inf->repstart=-1;
inf->id=-1;
inf->left.volume=32768;
inf->right.volume=32768;
inf->left.vls=0;
inf->right.vls=0;
free(wavinf);
if (find_chunk(snd,WAV_DATA)==0)
{
printf("Soubor %s je poskozen\n",wav);
fclose(snd);
return;
}
inf->size=get_chunk_size(snd);
fseek(snd,4,SEEK_CUR);
inf->snd=snd;
}
void calc_vls(TVOLSTRUC *vls)
{
vls->volslow--;
if (vls->volslow<=0)
{
vls->volslow+=vls->volsmax;
vls->volume+=vls->vls;
if ((vls->vls>0 && vls->volume>=vls->volume_end)||
(vls->vls<0 && vls->volume<=vls->volume_end))
{
vls->volume=vls->volume_end;
vls->vls=0;
}
}
}
void mix_buffer(int size)
{
int chan,i;
memset(source,0,size*2);
for(chan=0;chan<CHANNELS;chan++)
{
if (chaninfo[chan].snd!=NULL)
{
TCHANINFO *inf=chaninfo+chan;
for(i=0;i<size;i+=2)
{
int left,right;
if (inf->bit8)
{
fread(&left,1,1,inf->snd);left=(short)(left*256);
left^=0xffff8000;
inf->size--;
}
else
{
fread(&left,1,2,inf->snd);left=(short)left;
inf->size-=2;
}
if (inf->chans==1) right=left;
else
if (inf->bit8)
{
fread(&right,1,1,inf->snd);right=(short)(right*256);
right^=0xffff8000;
inf->size--;
}
else
{
fread(&right,1,2,inf->snd);right=(short)right;
inf->size-=2;
}
left=(int)left*inf->left.volume/(32768);
right=(int)right*inf->right.volume/(32768);
left=left*glob_volume/256;
right=right*glob_volume/256;
calc_vls(&inf->left);
calc_vls(&inf->right);
left+=source[i];
right+=source[i+1];
if (left>32767) left=32767;
if (left<-32767) left=-32767;
if (right>32767) right=32767;
if (right<-32767) right=-32767;
source[i]=left;
source[i+1]=right;
if (inf->size<=0)
{
if (inf->repstart!=-1)
{
fseek(inf->snd,0,SEEK_SET);
find_chunk(inf->snd,WAV_DATA);
inf->size=get_chunk_size(inf->snd);
fseek(inf->snd,4,SEEK_CUR);
fseek(inf->snd,inf->repstart,SEEK_CUR);
inf->size-=inf->repstart;
}
else
{
fclose(inf->snd);
inf->snd=NULL;
break;
}
}
}
}
}
}
void open_files(char *ntarget)
{
tf=open(ntarget,O_BINARY | O_RDWR);
if (!tf) abort();
lseek(tf,0,SEEK_SET);
read(tf,&gh,sizeof(gh));
memcpy(gh.ampl_table,ampl_table,sizeof(ampl_table));
gh.snd_freq=22050;
}
void read_frame()
{
long x;
read(tf,&x,4);
x>>=8;
next_frame=tell(tf)+x;
}
long find_sound_action()
{
long x;char c;
do
{
read(tf,&x,4);
c=x;x>>=8;
if (c==4) return x;
lseek(tf,x,SEEK_CUR);
}
while (1);
}
void press_sound_chunk()
{
int siz;
siz=find_sound_action();
mix_buffer(siz);
compress_buffer_stereo(siz);
write(tf,&target,siz);
}
void close_files()
{
int i;
lseek(tf,0,SEEK_SET);
write(tf,&gh,sizeof(gh));
fclose(sf);
close(tf);
for(i=0;i<CHANNELS;i++)
if (chaninfo[i].snd!=NULL)
{
fclose(chaninfo[i].snd);
chaninfo[i].snd=NULL;
}
}
void ozvuceni()
{
int i;
for(i=1;i<gh.frames;i++)
{
cprintf("frame %d\r",i);
read_frame();
press_sound_chunk();
lseek(tf,next_frame,SEEK_SET);
}
}
#define get_num(c,n) {sscanf(c,"%d",&n);while (*c==32) c++;c=strchr(c,32);}
int find_channel_id(int id)
{
int i;
for(i=0;i<256;i++) if (chaninfo[i].id==id) return i;
printf("Nemohu najit kanal s ID: %d\n",id);
return -1;
}
void interpret_line(FILE *f)
{
char line_buf[1024];
char *c=line_buf;
TVOLSTRUC *v;
TCHANINFO *inf;
int num;char fcid=0;
fgets(line_buf,1024,f);
while (c!=NULL)
{
while (*c==32) c++;
if (!*c) break;
if (*c=='@')
{
char command[24];
c++;
sscanf(c,"%23s",command);c=strchr(c,32);
strupr(command);
if (!strcmp(command,"ID"))
{
get_num(c,num);
if (fcid) chaninfo[last_channel].id=num;
fcid=0;
if ((last_channel=find_channel_id(num))==-1) return;
inf=chaninfo+last_channel;
}
else if (!strcmp(command,"R")) v=&inf->left;
else if (!strcmp(command,"L")) v=&inf->right;
else if (!strcmp(command,"VOL"))
{
get_num(c,num);
v->volume=num*128;
}
else if (!strcmp(command,"VOLEND"))
{
get_num(c,num);
v->volume_end=num*128;
v->vls=0;
}
else if (!strcmp(command,"SPEED"))
{
get_num(c,v->vls);v->volsmax=1;v->volslow=1;
if (v->volume>v->volume_end) v->vls=-v->vls;
}
else if (!strcmp(command,"SLOW"))
{
get_num(c,v->volsmax);v->vls=1;v->volslow=1;
if (v->volume>v->volume_end) v->vls=-v->vls;
}
else if (!strcmp(command,"REPSTART")){ get_num(c,inf->repstart);}
else if (!strcmp(command,"GLOBVOL")) {get_num(c,glob_volume);}
}
else
{
char filename[128];
sscanf(c,"%127s",filename);
c=strchr(c,32);
open_wav(filename);
inf=chaninfo+last_channel;
fcid=1;
}
}
}
void call_script(char *script_name)
{
FILE *scr,*snf;
char name[256];
char snd_name[256],*c;
int i,fr,lfr=0,wfr=-1;
scr=fopen(script_name,"r");
strcpy(snd_name,script_name);
c=strrchr(snd_name,'.');
if (c==NULL) strcat(snd_name,SND_NAME);
else strcpy(c,SND_NAME);
if (scr==NULL)
{
printf("Nemohu otev©¡t script: %s\n",script_name);
exit(1);
}
snf=fopen(snd_name,"r");
i=fscanf(scr,"%255s",name);
open_files(name);
if (i!=1)
{
printf("Chyba ve script souboru: %s. Prvni mus¡ b˜t jmno c¡lovho souboru.\n",scr);
exit(1);
}
while ((i=fgetc(scr))!=EOF && i!='\n');
for(fr=1;fr<gh.frames;fr++)
{
cprintf("frame %d\r",fr);
read_frame();
do
{
if (wfr==-1)
{
i=fgetc(scr);
if (i!=EOF)
{
if (i!='#')
{
fscanf(snf,"%d",&lfr);
while ((i=fgetc(scr))!=EOF && i!='\n');
}
else
{
fscanf(scr,"%d",&wfr);
wfr+=lfr-1;
}
}
else wfr=9999999;
}
if (wfr<=fr && wfr!=-1)
{
interpret_line(scr);
wfr=-1;
}
}
while (wfr==-1);
press_sound_chunk();
lseek(tf,next_frame,SEEK_SET);
}
fclose(scr);
if (snf!=NULL) fclose(snf);
}
main(int argc,char *argv[])
{
if (argc<2)
{
puts("\nPouziti: MGFSOUND film.mgf zvuk.wav [i]");
puts("\nnebo: MGFSOUND script.scr");
puts("\nKde _i_ je komprimacni krivka (viz SNDPACK) (default:4)");
exit(0);
}
if (argc>3)
{
sscanf(argv[3],"%d",&difftype);
}
Create_table_16();
if (argc==2)
call_script(argv[1]);
else
{
open_wav(argv[2]);
open_files(argv[1]);
ozvuceni();
}
close_files();
}

646
VIDEO/MGIF.C Normal file
View file

@ -0,0 +1,646 @@
// MOTION GIF - LZW komprimovana animace v rozliseni 320x180 256 barev avsak
// upravena pro prehravani v HICOLOR pro konkretni rezim (32768 barev)
// Format
/*
[ FRAME ] <pocet_chunku 1b><delka frame 3b>
[CHUNK] <cislo_akce 1b><delka_chunku 3b> !pozor delka je 3 bajtova (tj 16MB)
0 - PRADNY CHUNK
1 - LZW FULL SCREEN
2 - MGIF DELTA
3 - HICOLOR PALETE
4 - SOUND TRACK
5 - TEXT TRACK
6 - MGIF COPY
7 - SOUND INIT
Popis Chunku:
PRAZDNY_CHUNK - muze obsahovat soukrome informace
LZW_FULL_SCREEN
- ihned za hlavickou nasleduje LZW komprimovany obrazek
v rozliseni 320x180 256 barev
MGIF_DELTA
- cely blok je LZW komprimovany. Po dekomprimace blok obsahuje
dva druhy informaci. Prvni DWORD je ofset od pocatku dat
ktery ukazuje na zacatek graficke informace. Po tomto
DWORDU jsou ulozeny data o umisteni grafickych bodu v obrazu
Prvni byte znaci, kolik je nutne preskocit slov. (tj *2 byte)
Dalsi byte znaci, kolik je nutne zapsat slov (tj *2 byte)
Po tomto bytu je nutne prenest presne tolik slov z
grafickeho bloku na obrazovku. Dvojice bajtu se opakuji
dokud ani jeden z nich nema nejvyssi 2 bity nastavene.
Pak tento byte znaci ze uz na radce nic vic neni. Dolni cast
byte (tj 6 bitu) pak udava pocet radku, ktere je treba pre-
skocit. (nula=zadny).
HICOLOR PALETTE
- Prvni byte znamena pocet aktivnich barev. Pak nasleduje
paleta ve formatu xRRRRRGGGGGBBBBB. Rozdil oproti vsem
beznym paletam je v tom ze neni treba v palete udrzovat
barvy, ktere uz na obrazovce jsou, protoze zmena palety
se neprojevi na jiz zobrazenem obrazku.
SOUND_TRACK
- Kazdy frame obsahuje zvukovou stopu. Je to RAW format.
Pro verzi MGIF97 zde je zvukova informace ulozena ve
zvukove kvalite 16-bit stereo 22000Khz, ovsem komprimovana
na 50% jako MUS.
TEXT_TRACK
- Navic je ve mozne ve frame umistit textovou zpravu (titulek)
Prvni WORD udava dobu zobrazeni (pocet frame).
Pote nasleduje text zakoncen znakem 0;
MGIF_COPY - Za timto CHUNKEM je ulozen blok dat v nezakomprimovanem
tvaru(tj 57600byte);
*/
#include <stdio.h>
#include <stdlib.h>
#include <types.h>
#include <bgraph.h>
#include <memman.h>
#include <mem.h>
#include "flc.h"
#include "lzw.h"
#include <math.h>
#define MGIF "MGIF"
#define MGIF_Y "97"
#define VER 0x100
#define MGIF_EMPTY 0
#define MGIF_LZW 1
#define MGIF_DELTA 2
#define MGIF_PAL 3
#define MGIF_SOUND 4
#define MGIF_TEXT 5
#define MGIF_COPY 6
#define MGIF_SINIT 7
#define FRAME_X 320
#define FRAME_Y 180
#define FRAME_LEN (FRAME_X*FRAME_Y)
#define DELTA_LEN (3*FRAME_LEN)
#define LZW_LEN (2*FRAME_LEN)
#define SOUND_SPEED 44100
#define PRE_SOUND ((256*1024)/2)
#define ZTRATA lowq
#define BZTRATA colorq
#define MAX_FRAME max_fr
#define MIN_FRAME min_fr
short mult_table[64];
short square_table[4096];
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
word last_frame[FRAME_Y][FRAME_X];
char frame_delta[FRAME_LEN];
char delta_data[DELTA_LEN];
word color_state[32*32+32*32+32*32];
char calc_data[FRAME_LEN];
int delta_data_size;
int frame_delta_size;
int speed=20;
int last_frame_size;
int total_frames;
int lowq=0;
int colorq=0;
int max_fr=30000;
int min_fr=0;
int hranice;
int hdiff=0;
struct mgif_header gh;
char lzw_buffer[LZW_LEN];
char pal_use[256],color_map[256];
word hipal[256],max_colors;
FILE *mgf;
long of_pos;
int of_chunks;
void open_frame()
{
of_chunks=0;
of_pos=ftell(mgf);
fwrite(&of_pos,1,4,mgf);
}
void close_frame()
{
long fsize,p;
last_frame_size=fsize=(p=ftell(mgf))-of_pos-4;
fseek(mgf,of_pos,SEEK_SET);
fwrite(&of_chunks,1,1,mgf);
fwrite(&fsize,1,3,mgf);
fseek(mgf,p,SEEK_SET);
total_frames++;
}
void write_chunk(char action,long size,void *data)
{
fwrite(&action,1,1,mgf);
fwrite(&size,1,3,mgf);
fwrite(data,1,size,mgf);
of_chunks++;
}
void conv_2_hicolor()
{
int i,r,g,b;
for(i=0;i<256;i++)
{
r=(flc_paleta[i][0]>>3);
g=(flc_paleta[i][1]>>3);
b=(flc_paleta[i][2]>>3);
hipal[i]=((r<<10)+(g<<5)+b);
}
}
char find_color(word c); //najde barvu v palete a vraci byte
#pragma aux find_color parm [eax]=\
"mov edi,offset hipal"\
"mov ecx,256"\
"repne scasw"\
"mov eax,edi"\
"sub eax,offset hipal"\
"shr eax,1"\
"dec eax"\
value [al] modify[edi ecx];
void init_palmap()
{
int i;
memset(pal_use,0,sizeof(pal_use)); // nuluj pristupy k barvam
for(i=0;i<256;i++) color_map[i]=find_color(hipal[i]); //redukuj paletu;
max_colors=256; // pocet barev zatim 256;
}
char test_transp(char c,word w)
{
int r1,g1,b1;
int r2,g2,b2;
int diff;
r1=flc_paleta[c][0]>>3;
g1=flc_paleta[c][1]>>3;
b1=flc_paleta[c][2]>>3;
w&=0x7fff;
b2=w;g2=b2>>5;r2=g2>>5;b2&=0x1f;g2&=0x1f;
r1-=r2;g1-=g2;b1-=b2;
diff=abs(r1)+abs(g1<<1)+abs(b1);
return diff<=hranice;
}
void create_delta(char *frame_buffer)
{
char *delta;
char *data;
long colors2;
int x,y;
word *p;
char skip,skc,cpc;
char c1,c2,*a,d;
delta=delta_data;
data=frame_delta;
a=frame_buffer;
for(y=0;y<180;y++)
{
p=&last_frame[y];
skip=1;
skc=0;
cpc=0;
for(x=0;x<160;x++)
{
c1=*a++;c2=*a++;
c1=color_map[c1];
c2=color_map[c2];
d=test_transp(c1,p[0]) && test_transp(c2,p[1]);
if (d!=skip)
{
if (skip) *delta++=skc;else *delta++=cpc;
skip=!skip;skc=0;cpc=0;
}
if (!skip)
{
*data++=c1;
*data++=c2;
colors2=hipal[c1]+(hipal[c2]<<16);
*(long *)p=colors2;
cpc++;
}
else skc++;
p+=2;
pal_use[c1]=1;
pal_use[c2]=1;
}
if (!skip) *delta++=cpc;
if (skc==160 && *(delta-1)!=0xff && delta!=delta_data) delta[-1]++; //preskoc n radek
else *delta++=0xc0; //oznac konec radky
}
delta_data_size=delta-delta_data;
frame_delta_size=data-frame_delta;
}
void reduce_palette() //redukuje paletu na nejmensi nutny pocet barev
{
int i,j;
for(i=0,j=0;i<256;i++)
{
if (pal_use[i])
{
hipal[j]=hipal[i];
color_map[i]=j++;
}
}
max_colors=j;
}
void filter_colors(void *block,int size,void *colormap); //prefiltruje blok dat podle color_map
#pragma aux filter_colors parm [edi][ecx][ebx]=\
"lp1: mov al,[edi]"\
" xlatb"\
" stosb"\
" loop lp1"\
modify [eax];
void *join_two_blocks(void *d1,void *d2,int siz1,int siz2,long *celk)
{
long siz;
char *d;
void *x;
siz=siz1+siz2+4;
d=(char *)getmem(siz);
x=d;
memcpy(d,&siz1,4);d+=4;
memcpy(d,d1,siz1);d+=siz1;
memcpy(d,d2,siz2);
*celk=siz;
return x;
}
void create_last_frame(void *source,void *target,void *pal,int size);
#pragma aux create_last_frame parm [esi][edi][ebx][ecx]=\
"lp1: lodsb"\
" movzx eax,al"\
" mov eax,[eax*2+ebx]"\
" stosw"\
" loop lp1"\
modify[eax]
void create_mgif_pal()
{
write_chunk(MGIF_PAL,max_colors*2,hipal);
}
void create_mgif_lzw()
{
int siz;
conv_2_hicolor();
init_palmap();
create_mgif_pal();
filter_colors(frame_buffer,FRAME_LEN,color_map);
create_last_frame(frame_buffer,last_frame,hipal,FRAME_LEN);
init_lzw_compressor(8);
memset(lzw_buffer,0,sizeof(lzw_buffer));
siz=lzw_encode(frame_buffer,lzw_buffer,FRAME_LEN);
if (siz>FRAME_LEN) write_chunk(MGIF_COPY,FRAME_LEN,frame_buffer);
else write_chunk(MGIF_LZW,siz,lzw_buffer);
done_lzw_compressor(8);
}
void create_color_state()
{
int i;
int r1,g1,b1;
int r2,g2,b2;
int diff;
char *c;
word *w;
memset(color_state,0,sizeof(color_state));
c=frame_buffer;
w=last_frame;
for(i=0;i<FRAME_LEN;i++)
{
r1=flc_paleta[*c][0]>>3;
g1=flc_paleta[*c][1]>>3;
b1=flc_paleta[*c][2]>>3;
b2=*w;g2=b2>>5;r2=g2>>5;b2&=0x1f;g2&=0x1f;
r1-=r2;g1-=g2;b1-=b2;
diff=abs(r1)+abs(g1<<1)+abs(b1);
color_state[diff]++;
c++;w++;
}
}
void set_max_color_change(int cchange)
{
int i,s;
s=0;cchange=57600-cchange;
for(i=sizeof(color_state)/sizeof(word)-1;s<cchange && i>0;i--) s+=color_state[i];
if (s>=cchange) i++;
hranice=i+hdiff;if (hranice<0) hranice=0;
}
int rozptyl(int v1,int v2)
{
int c1,c2,x,s;
x=v1+v2>>1;
c1=(x-v1);
c2=(x-v2);
s=c1*c1+c2*c2;
return s;
}
void create_low_quality()
{
void *snd;int l;
char *sn,*sr,c1,c2;
int rs,bs,gs;
l=FRAME_LEN;
sr=frame_buffer;
snd=calc_data;
sn=(char *)snd;
l--;
while (l--)
{
c1=*sr++;
c2=*sr;
rs=rozptyl(flc_paleta[c1][0],flc_paleta[c2][0]);
gs=rozptyl(flc_paleta[c1][1],flc_paleta[c2][1]);
bs=rozptyl(flc_paleta[c1][2],flc_paleta[c2][2]);
if (rs+gs+bs<ZTRATA)
{
*sn++=c1;
*sn++=c1;
sr++;if(!l--) break;
}
else *sn++=c1;
}
create_delta(snd);
}
void create_mgif_delta()
{
void *d;
long siz;
conv_2_hicolor();
init_palmap();
if (BZTRATA) create_color_state();
set_max_color_change(BZTRATA);
create_low_quality();
if (delta_data_size+frame_delta_size>FRAME_LEN)
{
create_mgif_lzw();
return;
}
if (!frame_delta_size) return;
reduce_palette();
filter_colors(frame_delta,frame_delta_size,color_map);
d=join_two_blocks(delta_data,frame_delta,delta_data_size,frame_delta_size,&siz);
init_lzw_compressor(8);
memset(lzw_buffer,0,sizeof(lzw_buffer));
siz=lzw_encode(d,lzw_buffer,siz);
done_lzw_compressor();
free(d);
if (siz>FRAME_LEN)
{
create_mgif_lzw();
return;
}
write_chunk(MGIF_DELTA,siz,lzw_buffer);
create_mgif_pal();
}
void create_sound_track(int size)
{
void *p;
p=getmem(size);
memset(p,0,size);
write_chunk(MGIF_SOUND,size,p);
free(p);
}
void reserve_track()
{
int size;
size=SOUND_SPEED/speed;
size&=~1;
create_sound_track(size);
}
void prereserve_tracks()
{
int size;
int celk;
size=SOUND_SPEED/speed;
size&=~1;
celk=PRE_SOUND;
while (celk-size>0)
{
open_frame();
create_sound_track(size);
close_frame();
celk-=size;
}
if (celk)
{
open_frame();
create_sound_track(celk);
close_frame();
}
}
void fill_header(int frames)
{
memset(&gh,0,sizeof(gh));
strncpy(gh.sign,MGIF,4);
strncpy(gh.year,MGIF_Y,2);
gh.eof=26;
gh.ver=VER;
gh.frames=frames;
}
void show_screen()
{
word *c;
int i,j;
word *w;
c=last_frame;
w=screen;
for(i=0;i<180;i++)
{
for(j=0;j<320;j++)
{
*w++=*c;
*w++=*c;
c++;
}
w+=640;
}
showview(0,0,640,360);
showview(0,400,200,20);
}
void write_frame_size(int i,int col)
{
char s[20];
curcolor=0;bar(0,400,200,420);
sprintf(s,"%d %d %d",i,col,hranice);position(0,400);outtext(s);
}
compress_flc(char *name)
{
int x;
Open_FLC (name);
charcolors[0]=0;
charcolors[1]=0x7fff;
Get_first_frame ();
Decompress_frame ();
curcolor=0;bar(0,0,639,479);
open_frame();
create_mgif_lzw();
reserve_track();
close_frame();write_frame_size(last_frame_size,max_colors);
show_screen();
for (x=2; x<=h_flc.frames; x++)
{
Get_next_frame ();
Decompress_frame ();
open_frame();
create_mgif_delta();
reserve_track();
close_frame();
write_frame_size(last_frame_size,max_colors);
if (last_frame_size>MAX_FRAME) hdiff++;
else if (last_frame_size<MIN_FRAME && hranice>0) hdiff--;
else if (hdiff>0) hdiff--;else if(hdiff<0) hdiff++;
show_screen ();
}
Close_FLC();
}
void create_mgf_file(char *name)
{
mgf=fopen(name,"wb+");
fwrite(&gh,1,sizeof(gh),mgf);
total_frames=0;
prereserve_tracks();
}
void close_mgf_file()
{
fseek(mgf,0,SEEK_SET);
fill_header(total_frames);
fwrite(&gh,1,sizeof(gh),mgf);
fclose(mgf);
}
void create_mult_and_square()
{
int i;
puts("Creating tables...");
for(i=0;i<64;i++) mult_table[i]=(short)((i-32)*(i-32));
for(i=0;i<4096;i++) square_table[i]=(short)sqrt(i);
}
extern int sada7;
main(int argc,char *argv[])
{
puts("\n(C)1997 Komprimator Motion GIF v0.9 by Ondrej Novak");
if (argc<3)
{
puts("Pouziti:");putchar('\n');;
puts("MGIF source.flc target.mgf [speed] [lowq] [min_fr] [max_fr] [colorq]");putchar('\n');
puts("speed - Prehravaci rychlost ve snimkach za sekundu (pro 22050kHz)\n"
"lowq - Nejnizsi mozny rozptyl barev sousednich bodu (snizuje kvalitu\n"
" obrazu) (default: 0)\n"
"min_fr - Pozadavek na nejmensi velikost frame. Pod touto hranici v \n"
" nasledujicim frame snizi velikost ztraty (default: 0)\n"
"max_fr - Pozadavek na nejvetsi velikost frame. Pri prekroceni teto \n"
" hranice se zvysi ztrata o jeden bod. (default 30000)\n"
"colorq - Tato hodnota slouzi k predvidani velikosti ztraty. Udava\n"
" kolik bodu z celkoveho poctu zmen ve frame se menit nebude\n"
" Program pak vybere ty nejmensi rozdily a ty do rozdilove \n"
" mapy nezahrne. (default: 0)\n"
"Velikost nejmensiho rozdilu je zobrazen pri komprimaci jako treti cislo\n"
"Nula udava ze se nezapisuji jen ty body, ktere se nemeni.\n\n"
"Pozn: Bezne neni nutne uvadet parametr colorq protoze stupen ztraty se \n"
"voli podle vysledku predchoziho frame. Je dobre ho uvest pri velkych\n"
"vykyvech velikosti frame. Tak zhruba pri ñ10KB. Hodnoty parametru se \n"
"voli od 25000-35000, cim vyssi, tim vyssi stupen ztraty");
exit(0);
}
switch (argc)
{
case 8:sscanf(argv[7],"%d",&colorq);
case 7:sscanf(argv[6],"%d",&max_fr);
case 6:sscanf(argv[5],"%d",&min_fr);
case 5:sscanf(argv[4],"%d",&lowq);
case 4:sscanf(argv[3],"%d",&speed);
}
create_mgf_file(argv[2]);
initmode32();
curfont=(void *)&sada7;
compress_flc(argv[1]);
closemode();
puts("Zaviram Motion GIF...");
close_mgf_file();
}

376
VIDEO/MGIF98.C Normal file
View file

@ -0,0 +1,376 @@
#include <stdio.h>
#include <stdlib.h>
#include <bgraph.h>
#include <pcx.h>
#include <math.h>
#include <conio.h>
#include <mem.h>
#define PIC_XS 320
#define PIC_YS 184
#define HICOLOR 32768
#define PICTURE "TEST1.PCX"
#define PI 3.141592654
#define C(x) ((x)==0?0.5:1.0)
#define QUALITY 4
typedef signed char t_y_buffer[PIC_YS*PIC_XS];
typedef signed char t_cb_buffer[PIC_YS*PIC_XS/2];
typedef signed char t_cr_buffer[PIC_YS*PIC_XS/2];
typedef signed char T_COLORT[HICOLOR][3];
typedef short T_COLORIT[64][64][64];
t_y_buffer y_buff,y_buff_new;
t_cb_buffer cb_buff,cb_buff_new;
t_cr_buffer cr_buff,cr_buff_new;
T_COLORT colort;
T_COLORIT colorit;
/*char y_iquant[64]=
{
16,11,10,16,24,40,51,61,
12,12,14,19,26,58,60,55,
14,13,16,24,40,57,69,56,
14,17,22,29,51,87,80,61,
18,22,37,56,68,109,103,77,
24,35,55,64,81,104,113,92,
49,64,78,87,103,121,120,101,
72,92,95,98,112,100,103,99
};
*/
signed char y_iquant[64]=
{
4, 8, 9, 10,15,20,22,30,
8,8,9,11,16,21,24,30,
9,9,10,12,20,25,30,36,
9,10,11,13,25,30,35,38,
10,12,15,20,25,35,40,45,
11,14,20,27,41,50,55,60,
20,30,40,45,50,61,60,50,
32,48,49,51,50,51,50,49,
};
char test[]=
{
139,144,149,153,155,155,155,155,
144,151,153,156,159,156,156,156,
150,155,160,163,158,156,156,156,
159,161,162,160,160,159,159,159,
159,160,161,162,162,155,155,155,
161,161,161,161,160,157,157,157,
162,162,161,163,162,157,157,157,
162,162,161,161,163,158,158,158
};
signed char c_iquant[64]=
{
2,4,5,5,6,10,11,15,
4,4,5,5,8,10,12,15,
4,4,6,6,10,12,15,18,
4,5,5,6,12,15,17,18,
5,6,7,10,12,16,20,22,
6,7,10,13,20,25,26,30,
10,15,20,22,25,30,30,25,
16,24,25,26,25,26,25,25,
};
signed char koef_table[PIC_YS*PIC_XS];
short *picture;
char code_tab[][2]=
{
{0,0},{1,0},{0,1},{0,2},{1,1},{2,0},{3,0},{2,1},{1,2},{0,3},{0,4},{1,3},{2,2},
{3,1},{4,0},{5,0},{4,1},{3,2},{2,3},{1,4},{0,5},{0,6},{1,5},{2,4},{3,3},{4,2},
{5,1},{6,0},{7,0},{6,1},{5,2},{4,3},{3,4},{2,5},{1,6},{0,7},{1,7},{2,6},{3,5},
{4,4},{5,3},{6,2},{7,1},{7,2},{6,3},{5,4},{4,5},{3,6},{2,7},{3,7},{4,6},{5,5},
{6,4},{7,3},{7,4},{6,5},{5,6},{4,7},{5,7},{6,6},{7,5},{7,6},{6,7},{7,7}
};
signed char dct[64][64]; //v poradi [koef;x,y] - koef dle tabulky
signed char ict[64][64]; //v poradi [x,y;koef];koef dle tabulky
signed short mlt[256][256]; //[i,j]=i*j
signed char mlt2[256][256]; //[i,j]=i*j (s oriznutim)
void create_color_table(void)
{
int r,g,b;
int y,cb,cr,i;
puts("Creating SECAM CT table");
for(i=0;i<HICOLOR;i++)
{
r=i>>10;
g=(i>>5) & 0x1f;
b=i & 0x1f;
r<<=3;
g<<=3;
b<<=3;
y=(r*299+g*587+b*114)/1000;
cb=564*(b-y)/1000;
cr=713*(r-y)/1000;
colort[i][0]=y-128;
colort[i][1]=cb;
colort[i][2]=cr;
}
for(y=0;y<64;y++)
for(cb=-32;cb<31;cb++)
for(cr=-32;cr<31;cr++)
{
int y2=y<<2,cr2=cr<<3,cb2=cb<<3;
r=y2+cr2*1402/1000;
g=y2-(cb2*344+cr2*714)/1000;
b=y2+cb2*1772/1000;
r>>=3;
g>>=3;
b>>=3;
if (r>31) r=31;
if (g>31) g=31;
if (b>31) b=31;
if (r<0) r=0;
if (g<0) g=0;
if (b<0) b=0;
i=(r<<10)+(g<<5)+b;
colorit[(y-32)&63][cb&63][cr&63]=i;
}
}
#define NORMALIZE(i) if (i>127) i=127;else if (i<-128) i=-128;else;
void rozklad_obrazku(void)
{
int i;
for(i=0;i<PIC_XS*PIC_YS;i++)
{
int j=i>>1,k;
k=colort[picture[i+3]][0]-y_buff_new[i];
NORMALIZE(k);
y_buff[i]=k;
if (i & 1)
{
cb_buff[j]+=colort[picture[i+3]][1]>>2;
cr_buff[j]+=colort[picture[i+3]][2]>>2;
k=cb_buff[j]-cb_buff_new[j];NORMALIZE(k);
cb_buff[j]=k;
k=cr_buff[j]-cr_buff_new[j];NORMALIZE(k);
cr_buff[j]=k;
}
else
{
cb_buff[j]=colort[picture[i+3]][1]>>2;
cr_buff[j]=colort[picture[i+3]][2]>>2;
}
}
}
void slozeni_obrazku(void)
{
int i,x,y;
int yy,cb,cr,w;
unsigned short *ww;
i=0;
for(y=0;y<184;y++)
for(x=0;x<320;x++)
{
yy=y_buff_new[i]>>2;
cb=(cb_buff_new[i>>1]>>2);
cr=(cr_buff_new[i>>1]>>2);
w=colorit[yy&63][cb&63][cr&63];w=w+(w<<16);
ww=screen+x*2+y*1280;
ww[0]=w;ww[1]=w;
ww[640]=w;ww[641]=w;
//screen[x+y*640]=colorit[y_buff[i]>>2][16][16];
i++;
}
showview(0,0,0,0);
}
void create_dct(void)
{
int j,k,u,v,x,y;
puts("Creating DCT table:");
for(k=0;k<64;k++)
for(j=0;j<64;j++)
{
float res;
u=code_tab[j][0];
v=code_tab[j][1];
x=k & 7;y=k>>3;
res=127*cos((2*x+1)*u*PI/16)*cos((2*y+1)*v*PI/16);
dct[j][k]=(signed char)res;
}
}
void create_ict(void)
{
int j,k,u,v,x,y;
puts("Creating ICT table:");
for(j=0;j<64;j++)
for(k=0;k<64;k++)
{
float res;
u=code_tab[j][0];
v=code_tab[j][1];
x=k & 7;y=k>>3;
res=127*cos((2*x+1)*u*PI/16)*cos((2*y+1)*v*PI/16);
ict[k][j]=(signed char)res;
}
}
void create_mult()
{
int i,j,k;
puts("Creating MULT table:");
for(i=-128;i<128;i++)
for(j=-128;j<128;j++)
{
mlt[i & 0xff][j & 0xff]=i*j;
k=i*j;NORMALIZE(k);
mlt2[i & 0xff][j & 0xff]=k;
}
}
#define GET_DCT(i,k,p) (mlt[i][dct[k][p]])
#define GET_ICT(i,k,p) (mlt[i][ict[k][p]])
void dct_buffer(void *buffer,int box_x,int box_y,int linelen,char *quant)
{
int nextline=7*linelen;
int row,col,kn,pp;
char *c,*p;
signed char *ktab;
quant;
c=buffer;
ktab=koef_table;
for(row=0;row<box_y;row++)
{
for (col=0;col<box_x;col++)
{
char *kk=(char *)dct;
for(kn=0;kn<64;kn++)
{
int suma=0;
int u,v;
p=c;
u=code_tab[kn][0];
v=code_tab[kn][1];
for(pp=0;pp<64;)
{
suma+=mlt[(*p++)][(*kk++)];
pp++;if (!(pp & 7)) p+=linelen-8;
}
suma/=128;
suma>>=2;
suma*=C(u)*C(v);NORMALIZE(suma);
//suma/=quant[kn];
*ktab++=(signed char)(suma);
}
c+=8;
}
c+=nextline;
}
}
void ict_buffer(void *buffer,int box_x,int box_y,int linelen,char *quant)
{
int nextline=7*linelen;
int row,col,kn,pp;
signed char *c,*p;
signed char *ktab;
char kofs[64],ko=0;
quant;
c=buffer;
ktab=koef_table;
for(row=0;row<box_y;row++)
{
for (col=0;col<box_x;col++)
{
p=c;
for(pp=0;pp<64;)
{
int suma=0;
signed char *ictr=&ict[pp];
for(kn=0,ko=0;kn<64;kn++) if (ktab[kn]) {kofs[ko++]=kn;}
for(kn=0;kn<ko;kn++)
{
unsigned char kc=kofs[kn];
unsigned char cc=ktab[kc];
//int mult=mlt2[cc][quant[kn]];
//suma+=mlt[mult & 0xff][ictr[kn] & 0xff];
//int mult=(signed char)cc*(quant[kc]);
suma+=(signed char)cc*ictr[kc];
}
suma>>=7;
suma>>=2;
suma+=p[0];
NORMALIZE(suma);
p[0]=suma;p++;
pp++;if (!(pp & 7)) p+=linelen-8;
}
ktab+=64;
c+=8;
}
c+=nextline;
}
}
main()
{
char pcn[100];
int i;
create_color_table();
create_dct();
create_ict();
create_mult();
memset(y_buff_new,0,sizeof(y_buff_new));
memset(cr_buff_new,0,sizeof(cr_buff_new));
memset(cb_buff_new,0,sizeof(cb_buff_new));
//dct_buffer(test,1,1,8,y_iquant);
//ict_buffer(y_buff_new,40,23,320,y_iquant);
initmode32();
for(i=0;i<100;i++)
{
sprintf(pcn,"TEST%02d.PCX",i);
open_pcx(pcn,A_15BIT,(void **)&picture);
rozklad_obrazku();
free(picture);
dct_buffer(y_buff,40,23,320,y_iquant);
ict_buffer(y_buff_new,40,23,320,y_iquant);
dct_buffer(cr_buff,20,23,160,c_iquant);
ict_buffer(cr_buff_new,20,23,160,c_iquant);
dct_buffer(cb_buff,20,23,160,c_iquant);
ict_buffer(cb_buff_new,20,23,160,c_iquant);
//memcpy(y_buff_new,y_buff,sizeof(y_buff));
// memcpy(cr_buff_new,cr_buff,sizeof(cr_buff));
// memcpy(cb_buff_new,cb_buff,sizeof(cb_buff));
slozeni_obrazku();
}
getchar();
}

216
VIDEO/MGIFCAT.C Normal file
View file

@ -0,0 +1,216 @@
#include <types.h>
#include <stdio.h>
#include <mgifmem.h>
#include <mem.h>
#include <malloc.h>
#include <conio.h>
MGIF_HEADER_T mhead;
char nohead=1;
char turns[8]="||//--\\\\";
char turncnt;
void show_progress()
{
turncnt=(turncnt+1) & 0x7;
cprintf("> %c <\x8\x8\x8\x8\x8",turns[turncnt]);
}
void *load_frame(FILE *f,long *size,char *chunks)
{
long l;
int siz;
void *c;
if (!fread(&l,4,1,f)) return NULL;
siz=l>>8;
*chunks=l & 0xff;
*size=siz;
c=malloc(siz);
if (c==NULL) return NULL;
if (!fread(c,siz,1,f))
{
free(c);
return NULL;
}
return c;
}
char save_frame(FILE *f,char chunks,void *data,long size)
{
long l;
l=(size<<8)|chunks;
if (!fwrite(&l,4,1,f)) return 1;
if (!fwrite(data,size,1,f)) return 1;
return 0;
}
void *trans_frame(void *src,int size,char chunks,int soundtrk,long *outlen)
{
char *s,*t;
long l;
void *tg;
tg=malloc(size+soundtrk);
t=tg;s=src;
if (tg==NULL) return NULL;
while (chunks--)
{
l=*(long *)s;s+=sizeof(l);
if ((l & 0xff) !=MGIF_SOUND)
{
int size=l>>8;
memcpy(t,&l,sizeof(l));
t+=4;
memcpy(t,s,size);
t+=size;
s+=size;
}
else
{
long w;
w=(soundtrk<<8)|MGIF_SOUND;
*(long *)t=w;t+=4;
memset(t,0,soundtrk);
s+=l>>8;t+=soundtrk;
}
}
*outlen=t-(char *)tg;
return tg;
}
void *create_sound(int soundtrk, long *outlen)
{
void *tg;
char *t;
tg=malloc(soundtrk+4);
t=tg;
if (tg==NULL) return NULL;
*(long *)t=MGIF_SOUND|(soundtrk<<8);
t+=4;
memset(t,0,soundtrk);t+=soundtrk;
*outlen=t-(char *)tg;
return tg;
}
#define PRE_SOUND ((256*1024)/2)
int leading_track(FILE *f,int soundtrk)
{
int celk,siz;
void *p;long s;
char res;
int frames=0;
celk=PRE_SOUND;
while (celk)
{
if (celk>soundtrk) siz=soundtrk;else siz=celk;
p=create_sound(siz,&s);
celk-=siz;
res=save_frame(f,1,p,s);frames++;
free(p);
if (res) return 0;
}
return frames;
}
char copy_mgif(FILE *tg,FILE *src,int speed)
{
MGIF_HEADER_T sh;
int soundtrk=44100/speed;
void *p;char chunks;long size;
void *q;long qsize;
char skip_lead=0;
if (!fread(&sh,sizeof(sh),1,src)) return 2;
if (nohead)
{
int res;
mhead=sh,nohead=0;
fwrite(&mhead,sizeof(mhead),1,tg);
res=leading_track(tg,soundtrk);
if (!res) return 1;
mhead.frames=res;
}
while(sh.frames--)
{
p=load_frame(src,&size,&chunks);
if (p==NULL)return 1;
if (chunks!=1 || skip_lead)
{
q=trans_frame(p,size,chunks,soundtrk,&qsize);
if (q==NULL) {free(p);return 1;}
if (save_frame(tg,chunks,q,qsize)) {free(p);free(q);return 1;}
mhead.frames+=1;
free(q);
show_progress();
skip_lead=1;
}
free(p);
}
return 0;
}
char add_mgif(FILE *tg,char *filename,int speed)
{
FILE *src;
char res;
src=fopen(filename,"rb");
if (src==NULL) return 255;
res=copy_mgif(tg,src,speed);
close(src);
return res;
}
int main(int argc,char *argv[])
{
int ac;
int speed;
FILE *f;
if (argc<4)
{
puts("Malo parametru. Pouziti:\n"
"\n"
"MGIFCAT <rychlost> <cil.mgf> <zdroj1.mgf> [zdroj2.mgf [zdroj3.mgf [...]]]\n"
"\n"
"Rychlost je ve frames za sekundu\n"
"POZOR! Cilovy soubor bude prepsan! Neprenasi zvukove stopy!");
return 1;
}
ac=3;
if (sscanf(argv[1],"%d",&speed)!=1)
{
printf("Neplatna rychlost: %s\n",argv[1]);
return 1;
}
f=fopen(argv[2],"wb");
if (f==NULL)
{
printf("Nemohu otevrit vystupni soubor: %s\n",argv[2]);
return 1;
}
nohead=1;
while (ac<argc)
{
cprintf("Pripojuji soubor %s ",argv[ac]);
switch (add_mgif(f,argv[ac],speed))
{
case 1:cputs("Nastala nejaka chyba.\n\r");return 1;
case 2:cputs("Neplatny MGF soubor.");break;
case 255:cputs("Soubor nenalezen.");break;
default: cputs ("..OK..");
}
cputs("\n\r");
ac++;
}
fseek(f,0,SEEK_SET);
fwrite(&mhead,sizeof(mhead),1,f);
fclose(f);
return 0;
}

906
VIDEO/MGIFEACT.C Normal file
View file

@ -0,0 +1,906 @@
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <malloc.h>
#include <memman.h>
#include <event.h>
#include <bmouse.h>
#include <gui.h>
#include <basicobj.h>
#include <zvuk.h>
#include <bgraph.h>
#include <mgifmem.h>
#include <strlite.h>
#include <strlists.h>
#include "lzw.h"
#include "mgifeobj.h"
#include "mgifedit.h"
#include "mgifeact.h"
#include "mgifebld.h"
#define PRJ ".PRJ"
FRAME_DEFS_T *mgf_frames=NULL;
MGIF_HEADER_T mgf_header;
char *mgif_filename;
word preview_frame[320*180+3];
word check1;
word work_frame[320*180];
word check2;
word frame_shift;
TRACK_INFO_T *smp_prg=NULL;
int samples_total=0;
int last_unchanged_frame=0;
long total_frames=0;
void set_mgif(char *filename)
{
mgif_filename=NewArr(char,strlen(filename)+1);
strcpy(mgif_filename,filename);
}
#define error_exit(f,n) {fclose(f);return (n);}
int examine_mgif_file(char (*progress)(int perc))
{
FILE *f;
MGIF_HEADER_T head;
int r;
int frame_size=0;
char chunks;
int chunk_size=0;
char chunk_type;
int frame,chunk;
int track_size=-1;
FRAME_DEFS_T *fd;
FRAME_DEFS_T *fg;
char fgp=0;
frame_shift=0;
f=fopen(mgif_filename,"rb");
if (f==NULL) return EX_NOT_FOUND;
r=fread(&head,1,sizeof(head),f);
if (r!=sizeof(head)) error_exit(f,EX_READ_ERROR);
memcpy(&mgf_header,&head,sizeof(head));
total_frames=head.frames;
mgf_frames=NewArr(FRAME_DEFS_T,total_frames);
memset(mgf_frames,0,sizeof(FRAME_DEFS_T)*total_frames);
fg=fd=mgf_frames;
for(frame=0;frame<total_frames;frame++,fd++,fg+=fgp,frame_shift+=!fgp)
{
char sound=0;
fd->frame_start=ftell(f);
if (fread(&chunks,1,1,f)!=1) error_exit(f,EX_READ_ERROR);
if (fread(&frame_size,1,3,f)!=3) error_exit(f,EX_READ_ERROR);
for(chunk=0;chunk<chunks;chunk++)
{
if (fread(&chunk_type,1,1,f)!=1) error_exit(f,EX_READ_ERROR);
if (fread(&chunk_size,1,3,f)!=3) error_exit(f,EX_READ_ERROR);
switch(chunk_type)
{
case MGIF_LZW:
case MGIF_DELTA:
case MGIF_COPY: fg->display_start=ftell(f);
fg->displ_type=chunk_type;
fg->display_size=chunk_size;
fgp=1;
break;
case MGIF_SOUND:fd->sound_start=ftell(f);
track_size=chunk_size;
sound=1;
fd->track_size=track_size;
break;
case MGIF_PAL: fg->pal_start=ftell(f);
break;
}
fseek(f,chunk_size,SEEK_CUR);
}
fd->changed=1;fd->vol_save=0;
if (!sound) error_exit(f,EX_NO_SOUND);
if (progress(frame*100/total_frames)) break;
}
fclose(f);
return EX_NO_ERROR;
}
int add_sample(char *sample)
{
char *d;
d=NewArr(char,strlen(sample)+1);
strcpy(d,sample);
samples_total++;
smp_prg=grealloc(smp_prg,samples_total*sizeof(TRACK_INFO_T));
smp_prg[samples_total-1].sample_name=d;
smp_prg[samples_total-1].loop_start=-1;
smp_prg[samples_total-1].loop_end=-1;
smp_prg[samples_total-1].user_name=NULL;
smp_prg[samples_total-1].levy=NULL;
smp_prg[samples_total-1].pravy=NULL;
smp_prg[samples_total-1].starts=NULL;
smp_prg[samples_total-1].starts_count=0;
return samples_total-1;
}
void remove_sample(int id)
{
TRACK_DATA_T *p,*q;
if (id>=samples_total) return;
p=smp_prg[id].levy;
while(p!=NULL)
{
q=p->next;free(p);p=q;
}
p=smp_prg[id].pravy;
while(p!=NULL)
{
q=p->next;free(p);p=q;
}
free(smp_prg[id].starts);
free(smp_prg[id].sample_name);
free(smp_prg[id].user_name);
samples_total--;
if (id!=samples_total)memcpy(smp_prg+id,smp_prg+id+1,(samples_total-id)*sizeof(TRACK_INFO_T));
smp_prg=grealloc(smp_prg,samples_total*sizeof(TRACK_INFO_T));
}
void build_sample_list(void *list)
{
TSTR_LIST ls;
int id;
memcpy(&ls,list,sizeof(void **));
if (ls!=NULL) release_list(ls);
ls=create_list(samples_total+1);
for(id=0;id<samples_total;id++)
{
char *c;
if (smp_prg[id].user_name!=NULL) c=smp_prg[id].user_name;
else
{
c=strrchr(smp_prg[id].sample_name,'\\');
if (c==NULL) c=smp_prg[id].sample_name;else c++;
}
str_add(&ls,c);
}
if (samples_total==0) str_add(&ls,"< dn˜ zvuk>");
memcpy(list,&ls,sizeof(void **));
}
char get_vpoint(TRACK_DATA_T *track,int frame,TRACK_DATA_T *vp)
{
int fr;
TRACK_DATA_T *p,*q;
if (track==NULL)
{
vp->vpoint1=0;
vp->vpoint2=0;
vp->time=total_frames-frame;
vp->next=NULL;
return 1;
}
fr=0;
q=p=track;
while (p!=NULL && p->time+fr<=frame)
{
fr+=p->time;
q=p;
p=p->next;
}
if (p!=NULL)
if (fr==frame)
{
memcpy(vp,p,sizeof(*vp));
return 0;
}
else
{
int dif;
int half;
fr=frame-fr;
half=p->time/2;
dif=(p->vpoint2-p->vpoint1);
vp->vpoint1=p->vpoint1+(dif*fr+half)/p->time;
vp->vpoint2=p->vpoint2;
vp->time=p->time-fr;
vp->next=p->next;
}
else
{
vp->vpoint1=vp->vpoint2=q->vpoint2;
vp->time=total_frames-frame;
vp->next=NULL;
}
return 1;
}
void add_vpoint(TRACK_DATA_T **track,int frame)
{
TRACK_DATA_T *p,*z;
int fr,alltime;
p=*track;
if (p==NULL)
{
z=New(TRACK_DATA_T);
get_vpoint(p,0,z);
*track=z;
z->next=NULL;
add_vpoint(track,frame);
return;
}
fr=0;
while (p!=NULL && fr+p->time<=frame)
{
fr+=p->time;
p=p->next;
}
if (p==NULL) crash("Frame out of range!");
if (fr==frame) return;
alltime=p->time;
p->time=frame-fr;
z=New(TRACK_DATA_T);
z->vpoint1=p->vpoint1+((p->vpoint2-p->vpoint1)*p->time+alltime/2)/alltime;
z->vpoint2=p->vpoint2;
z->changed=1;p->changed=1;
p->vpoint2=z->vpoint1;
z->next=p->next;
p->next=z;
z->time=alltime-p->time;
}
void change_vpoint_spacing(TRACK_DATA_T *track,int frame,int value)
{
TRACK_DATA_T *p,*q;
int fr;
p=track;
if (track==NULL) return;
while (p->next!=NULL) p=p->next;
if (p->time<=value) value=p->time-1;
if (!value) return;
q=track;fr=0;
while (q!=NULL && q->time+fr<=frame)
{
fr+=q->time;
q=q->next;
}
if (q==NULL) return;
if (fr+q->time+value<=frame) return;
if (q->time+value<1) return;
if (fr<last_unchanged_frame) last_unchanged_frame=fr;
q->time+=value;
p->time-=value;
}
void set_vpoint(TRACK_DATA_T **track,int frame,int vp1,int vp2)
{
int fr=0;
TRACK_DATA_T *p,*q;
add_vpoint(track,frame);
p=*track;q=NULL;
while (p!=NULL && fr!=frame)
{
fr+=p->time;
q=p;
p=p->next;
}
p->changed=1;
p->vpoint1=vp2;
if (q!=NULL)
{
q->vpoint2=vp1;
q->changed=1;
}
}
void add_restart(TRACK_INFO_T *ti,int frame)
{
int *p=ti->starts;
int sc=ti->starts_count;
int i;
for(i=0;i<sc;i++) if (p[i]==frame) return;else if (p[i]>frame) break;
p=grealloc(p,sizeof(int)*(sc+1));
p[sc]=frame;
for(i=sc-1;i>=0;i--)
{
if (p[i]>p[i+1])
{
p[i]^=p[i+1];
p[i+1]^=p[i];
p[i]^=p[i+1];
}
}
ti->starts=p;
ti->starts_count++;
}
void delete_restart(TRACK_INFO_T *ti,int frame)
{
int i;
int *p=ti->starts;
int sc=ti->starts_count;
for(i=0;i<sc;i++) if (p[i]>frame) return;else if (p[i]==frame) break;
if (i==sc) return;
memcpy(p+i,p+i+1,sizeof(int)*(sc-i-1));
p=grealloc(p,sizeof(int)*(sc-1));
ti->starts=p;
ti->starts_count--;
}
void delete_vpoint(TRACK_DATA_T **track,int frame)
{
int fr;
TRACK_DATA_T *p,*q;
fr=0;
p=*track;
if (p==NULL) return;
q=NULL;
while (p!=NULL && fr!=frame)
{
fr+=p->time;
q=p;p=p->next;
}
if (p==NULL) return;
if (q==NULL)
{
if (p->next!=NULL)
{
*track=p->next;
p->next->vpoint1=p->vpoint1;
p->next->time+=p->time;
}
else
{
*track=NULL;
}
free(p);
}
else
{
q->next=p->next;
q->vpoint2=p->vpoint2;
q->time+=p->time;
free(p);
}
return;
}
char join_two_frames(void *source,void *target);
#pragma aux join_two_frames parm[esi][edi]=\
"mov ecx,57600"\
"xor bl,bl"\
"lp1: lodsw"\
" test [edi],0x8000"\
" jz sk1"\
" mov [edi],ax"\
" or bl,ah"\
"sk1: add edi,2"\
" dec ecx"\
" jnz lp1"\
modify[ecx eax] value[bl];
void build_frame(int frame_num,int *exit)
{
void *data_buff;
void *delta_buff;
void *p;
word palette[256];
FILE *f;
FRAME_DEFS_T *fd=mgf_frames+frame_num;
char full=0;
int counter=0;
static last_frame=-1;
char fast,flash;
static zavora=0;
if (last_frame==frame_num)
{
*exit=0;
return;
}
if (frame_num>=total_frames) crash("frame_num>=total_frames");
if (frame_num-last_frame!=1)
{
memset(preview_frame,0x80,sizeof(preview_frame));
memset(work_frame,0x80,sizeof(work_frame));
p=work_frame;fast=0;
}
else
{
p=preview_frame+3;
last_frame=frame_num;
fast=1;
}
preview_frame[0]=320;
preview_frame[1]=180;
preview_frame[2]=15;
while (zavora==1) task_sleep(NULL);
zavora=1;
f=fopen(mgif_filename,"rb");
data_buff=getmem(100000);
delta_buff=getmem(100000);
init_lzw_compressor(8);
do
{
reinit_lzw();
if (fd->pal_start)
{
fseek(f,fd->pal_start,SEEK_SET);
fread(palette,1,sizeof(palette),f);
}
if (fd->display_start)
{
fseek(f,fd->display_start,SEEK_SET);
fread(data_buff,1,fd->display_size,f);
switch (fd->displ_type)
{
case MGIF_LZW:lzw_decode(data_buff,delta_buff);
show_full_lfb12e(delta_buff,p,palette);
break;
case MGIF_DELTA:lzw_decode(data_buff,delta_buff);
show_delta_lfb12e(delta_buff,p,palette);
break;
case MGIF_COPY:show_full_lfb12e(data_buff,p,palette);
break;
}
if (!fast) full=!(join_two_frames(work_frame,preview_frame+3) & 0x80);
if (!((counter++) & 0xf) || full)
{
c_set_value(win_preview,10,0);
c_set_value(win_preview,10,(int)&preview_frame);
c_set_value(win_preview,5,(full||fast)?LABELCOLOR:(flash?0x7c00:0x3e0));
flash=!flash;
if (waktual->id!=win_preview)redraw_desktop();
}
if (!fast) task_sleep(NULL);
if (task_info[curtask]) break;
}
fd--;
}
while (fd>=mgf_frames && !full && !fast);
done_lzw_compressor();
free(data_buff);
free(delta_buff);
fclose(f);
if (full) last_frame=frame_num;
zavora=0;
*exit=0;
}
extern char backsndbuff[BACK_BUFF_SIZE];
extern volatile long backsnd;
extern volatile long backstep;
extern volatile int backfine;
extern long vals_save;
static stop_preview_flag=0;
static void *bufpos;
void preview_block(int start_frame,int x, int y)
{
word *scr;
void *data_buff;
char *dt;
void *delta_buff;
word *palette;
FILE *f;
FRAME_DEFS_T *fd=mgf_frames+start_frame;
int i;
char chunks;
int fsize,shift;
char chunk_type;
int chunk_size;
schovej_mysku();
zobraz_mysku();
stop_preview_flag=0;
if (banking)scr=screen+640*y+x;else scr=(word *)lbuffer+640*y+x;
memset(backsndbuff,0,sizeof(backsndbuff));
i=total_frames-start_frame;
bufpos=NULL;
if (!i) return;
start_mixing();
f=fopen(mgif_filename,"rb");
data_buff=getmem(100000);
delta_buff=getmem(100000);
shift=frame_shift;
fseek(f,fd->frame_start,SEEK_SET);
init_lzw_compressor(8);
backsnd=0;backstep=0x10000;vals_save=fd->vol_save;
do
{
char *gr,*s;char grtype;
long ssize;
fread(&fsize,1,4,f);chunks=fsize & 0xff;fsize>>=8;
fread(data_buff,1,fsize,f);
dt=data_buff;
grtype=0xff;
while (chunks--)
{
chunk_size=*(int *)dt;dt+=4;
chunk_type=chunk_size&0xff;chunk_size>>=8;
switch(chunk_type)
{
case MGIF_PAL:palette=(word *)dt;break;
case MGIF_LZW:
case MGIF_DELTA:reinit_lzw();lzw_decode(dt,delta_buff);grtype=chunk_type;break;
case MGIF_COPY:gr=dt;grtype=chunk_type;break;
case MGIF_SOUND:s=dt;ssize=chunk_size;break;
}
dt+=chunk_size;
}
do_events();
while (test_next_frame(bufpos,ssize)) do_events();
bufpos=sound_decompress(s,bufpos,ssize,&mgf_header.ampl_table);
if (!shift)
{
switch(grtype)
{
case MGIF_LZW: show_full_interl_lfb130(delta_buff,scr,palette);break;
case MGIF_DELTA:show_delta_interl_lfb130(delta_buff,scr,palette);break;
case MGIF_COPY:show_full_interl_lfb130(gr,scr,palette);break;
}
if (banking) showview(x,y,320,180);
}
else shift--;
fd++;
}
while (--i && !stop_preview_flag && !exit_wait);
done_lzw_compressor();
free(data_buff);
free(delta_buff);
fclose(f);
stop_mixing();
exit_wait=0;
}
void stop_preview()
{
stop_preview_flag=1;
}
void save_track(FILE *f,TRACK_DATA_T *t,char *id)
{
fprintf(f,"%s ",id);
while (t!=NULL)
{
fprintf(f,"%d %d %d ",t->vpoint1,t->vpoint2,t->time);
t=t->next;
}
fprintf(f,"\n");
}
void save_starts(FILE *f,int *p,int pocet)
{
int i;
fprintf(f,"%s %d ","START",pocet);
for(i=0;i<pocet;i++) fprintf(f,"%d ",p[i]);
fprintf(f,"\n");
}
void save_project(char *project_name)
{
FILE *f;
int i;
TRACK_INFO_T *ti;
f=fopen(project_name,"w");
fprintf(f,"%d %d\n",samples_total,amplifikace);
for(i=0,ti=smp_prg;i<samples_total;i++,ti++)
{
fprintf(f,"#%d",i);
fprintf(f,"TRACK %s%s%d %d %d\n",ti->sample_name,ti->user_name==NULL?"":ti->user_name,
ti->loop_start,ti->loop_end,ti->starts_count);
save_track(f,smp_prg[i].levy,"LEFT");
save_track(f,smp_prg[i].pravy,"RIGHT");
save_starts(f,smp_prg[i].starts,smp_prg[i].starts_count);
if (smp_prg[i].muted) fputs("MUTED\n",f);
}
fclose(f);
}
void *get_project_name(char *name)
{
char *c,*d;
c=NewArr(char,strlen(name)+7);
strcpy(c,name);
d=strrchr(c,'\\');if (d==NULL) d=c;
d=strchr(d,'.');if (d!=NULL) *d=0;
strcat(c,PRJ);
return c;
}
static void skip_space(FILE *f)
{
int c;
while ((c=getc(f))==32);
ungetc(c,f);
}
static void skip_nline(FILE *f)
{
int c;
while ((c=getc(f))!='\n' && c!=EOF);
}
static void *load_track(FILE *f)
{
TRACK_DATA_T *p,*st;
int vp1,vp2,tim,i;
st=NULL;
i=fscanf(f,"%d %d %d",&vp1,&vp2,&tim);
while (i==3)
{
if (st==NULL) p=st=New(TRACK_DATA_T);
else p=(p->next=New(TRACK_DATA_T));
p->next=NULL;
p->vpoint1=vp1;
p->vpoint2=vp2;
p->time=tim;
p->changed=0;
i=fscanf(f,"%d %d %d",&vp1,&vp2,&tim);
}
return st;
}
static void load_starts(FILE *f,int **pole,int *pocet)
{
int i;
fscanf(f,"%d",pocet);
*pole=NewArr(int,*pocet);
for(i=0;i<*pocet;i++) fscanf(f,"%d",*pole+i);
}
int load_project(char *prj_name)
{
FILE *f;
int p,i,j;
TRACK_INFO_T *ti;
f=fopen(prj_name,"r");
if (f==NULL) return 0;
fscanf(f,"%d %d",&p,&amplifikace);skip_nline(f);
smp_prg=NewArr(TRACK_INFO_T,p);
for(i=0;i<p;i++)
{
char s[20];
skip_space(f);
if (getc(f)!='#') {fclose(f);return -1;}
fscanf(f,"%d",&j);
ti=smp_prg+j;
ti->levy=NULL;ti->pravy=NULL;ti->starts=NULL;
do
{
skip_space(f);
j=getc(f);ungetc(j,f);
if (j=='#') break;
if (j=='\n')
{
skip_nline(f);
continue;
}
if (j==EOF) break;
fscanf(f,"%s",s);skip_space(f);
if (!strcmp(s,"TRACK"))
{
char s[256];
ti->muted=0;
fscanf(f,"%[^]",s);
ti->sample_name=NewArr(char,strlen(s)+1);strcpy(ti->sample_name,s);
getc(f);s[0]=0;
fscanf(f,"%[^]",s);
if (s[0])
{
ti->user_name=NewArr(char,strlen(s)+1);strcpy(ti->user_name,s);
}
else
ti->user_name=NULL;
getc(f);
fscanf(f,"%d %d %d",&ti->loop_start,&ti->loop_end,&ti->starts_count);
}
else if (!strcmp(s,"LEFT")) ti->levy=load_track(f);
else if (!strcmp(s,"RIGHT")) ti->pravy=load_track(f);
else if (!strcmp(s,"START")) load_starts(f,&ti->starts,&ti->starts_count);
else if (!strcmp(s,"MUTED")) ti->muted=1;
else {fclose(f);return -1;}
if (feof(f))
{
fclose(f);return -2;
}
skip_nline(f);
}
while (1);
}
samples_total=p;
return 0;
}
void set_changed_full_track(TRACK_INFO_T *tr)
{
set_changed_range(last_unchanged_frame,total_frames-1);
set_changed_track(tr->levy);
set_changed_track(tr->pravy);
last_unchanged_frame=total_frames;
}
static void do_vol_table_track(TRACK_DATA_T *tr,int indx,char action)
{
int i;
int fr;
int p;
TRACK_DATA_T v;
FRAME_DEFS_T *d;
for(i=0,fr=0,d=mgf_frames;i<total_frames && tr!=NULL;i++,d++)
{
get_vpoint(tr,i-fr,&v);
p=v.vpoint1+(v.vpoint2-v.vpoint1)/v.time;
if (action) d->changed|=(d->last_vol[indx]!=p);
d->last_vol[indx]=p;
if (v.time==1)
{
fr+=tr->time;
tr=tr->next;
}
}
}
void read_vol_table(TRACK_INFO_T *tr)
{
do_vol_table_track(tr->levy,0,0);
do_vol_table_track(tr->pravy,1,0);
}
void compare_vol_table(TRACK_INFO_T *tr)
{
do_vol_table_track(tr->levy,0,1);
do_vol_table_track(tr->pravy,1,1);
}
void set_vol_table_nul(void)
{
int i;
FRAME_DEFS_T *d;
for(i=0,d=mgf_frames;i<total_frames;i++,d++)
{
d->last_vol[0]=0;
d->last_vol[1]=0;
}
}
static long get_track_size(TRACK_INFO_T *tr)
{
long size1=0,size2=0;
TRACK_DATA_T *l,*r;
l=tr->levy;
r=tr->pravy;
while (l!=NULL) size1+=l->time,l=l->next;
while (r!=NULL) size2+=r->time,r=r->next;
if (size2>size1) return size2;else return size1;
}
static void track_dopln_na_konci(TRACK_INFO_T *tr)
{
long size1=0,size2=0;
TRACK_DATA_T *l,*r;
l=tr->levy;
r=tr->pravy;
while (l->next!=NULL) size1+=l->time,l=l->next;
while (r->next!=NULL) size2+=r->time,r=r->next;
l->time=total_frames-size1;
r->time=total_frames-size2;
}
void warn_size_mistmach(void)
{
int size=total_frames;
int sizeh=size;
int i;
for(i=0;i<samples_total;i++)
{
int s=get_track_size(smp_prg+i);
if (s<size) size=s;
if (s>sizeh) sizeh=s;
}
if (size<total_frames)
{
msg_box(PRG_HEADER,'\x1',"MGIFEDIT zjistil, e film je del¨i, ne stopy "
"uloen v souboru PRJ. Program tyto stopy dopln¡ na konci. Ke spr vnmu "
"um¡stˆn¡ pouij funkci GInsert","Ok",NULL);
for(i=0;i<samples_total;i++) track_dopln_na_konci(smp_prg+i);
}
if (sizeh>total_frames)
{
msg_box(PRG_HEADER,'\x1',"MGIFEDIT zjistil,e film je krat¨¡, ne stopy "
"uloen v souboru PRJ. Ke spr vnmu um¡stˆn¡ pouij funkci GDelete","Ok",NULL);
}
}
int get_inserted_frames(int frame)
{
int s;
frame+=1;
s=1;
while (frame<total_frames)
{
char c=mgf_frames[frame].displ_type;
if (c==MGIF_LZW || c==MGIF_COPY) return s;
frame++;
s++;
}
return s;
}
int get_deleted_frames(void)
{
int size=total_frames;
int sizeh=size;
int i;
for(i=0;i<samples_total;i++)
{
int s=get_track_size(smp_prg+i);
if (s<size) size=s;
if (s>sizeh) sizeh=s;
}
return sizeh-total_frames;
}
void insert_global(int frame,int count)
{
int i;
for(i=0;i<samples_total;i++)
{
change_vpoint_spacing(smp_prg[i].levy,frame,count);
change_vpoint_spacing(smp_prg[i].pravy,frame,count);
}
}
void delete_global(int frame,int count)
{
int i,j;
TRACK_DATA_T vl,vp;
for(i=0;i<samples_total;i++)
{
get_vpoint(smp_prg[i].levy,frame,&vl);
get_vpoint(smp_prg[i].pravy,frame,&vp);
for(j=0;j<count;j++) if (frame+j>0)
{
delete_vpoint(&smp_prg[i].levy,frame+j);
delete_vpoint(&smp_prg[i].pravy,frame+j);
}
change_vpoint_spacing(smp_prg[i].levy,frame,-count);
change_vpoint_spacing(smp_prg[i].pravy,frame,-count);
track_dopln_na_konci(smp_prg+i);
set_vpoint(&smp_prg[i].levy,frame,vl.vpoint1,vl.vpoint1);
set_vpoint(&smp_prg[i].pravy,frame,vp.vpoint1,vp.vpoint1);
}
}

98
VIDEO/MGIFEACT.H Normal file
View file

@ -0,0 +1,98 @@
#ifndef _MGIFEACT_H
#include <mgifmem.h>
#define _MGIFEACT_H
#define EX_NO_ERROR 0
#define EX_NOT_FOUND -1
#define EX_NO_SOUND -2
#define EX_READ_ERROR -3
#define EX_SOUND_ERROR -4
typedef struct frame_defs
{
long frame_start;
long display_start;
long pal_start;
long sound_start;
word displ_type;
long display_size;
long track_size;
char changed;
char last_vol[2];
long vol_save;
}FRAME_DEFS_T;
extern FRAME_DEFS_T *mgf_frames;
extern MGIF_HEADER_T mgf_header;
extern char *mgif_filename;
extern long total_frames;
extern int samples_total;
extern word frame_shift;
int examine_mgif_file(char (*progress)(int perc));
void set_mgif(char *filename);
typedef struct track_data_t
{
char vpoint1;
char vpoint2;
char changed;
int time; //0 odpovida restartu. Pak vpointy neplati
struct track_data_t *next;
}TRACK_DATA_T;
typedef struct track_info_t
{
char *sample_name;
char *user_name;
int loop_start;
int loop_end;
TRACK_DATA_T *levy,*pravy;
int *starts;
int starts_count;
char muted;
}TRACK_INFO_T;
extern TRACK_INFO_T *smp_prg;
int add_sample(char *sample_name);
void remove_sample(int id);
void build_sample_list(void *list);
char get_vpoint(TRACK_DATA_T *track,int frame,TRACK_DATA_T *vp); //neexistuje-li spocita se (return 1)
void set_vpoint(TRACK_DATA_T **track,int frame,int vp1,int vp2); //pokud neexistuje tak se vytvori
void add_vpoint(TRACK_DATA_T **track,int frame);
void add_restart(TRACK_INFO_T *ti,int frame);
void delete_restart(TRACK_INFO_T *ti,int frame);
void delete_vpoint(TRACK_DATA_T **track,int frame);
void change_vpoint_spacing(TRACK_DATA_T *track,int frame,int value);
void lzw_decode(void *source,char *target);
void init_lzw_compressor(int dic_size);
void reinit_lzw();
void done_lzw_compressor();
void preview_block(int start_frame,int x, int y);
void stop_preview();
void build_frame(int frame_num,int *exit);//TASK!
#pragma aux build_frame parm[]
void save_project(char *project_name);
int load_project(char *prj_name);
void *get_project_name(char *name);
void read_vol_table(TRACK_INFO_T *tr);
void compare_vol_table(TRACK_INFO_T *tr);
void set_vol_table_nul(void);
void set_changed_full_track(TRACK_INFO_T *tr);
void warn_size_mistmach(void);
int get_inserted_frames(int frame); //tracuje film a odhaduje kolik framu bylo pridano
int get_deleted_frames(void);
void insert_global(int frame,int count); //prida count framu od framu frame.
void delete_global(int frame,int count); //prida count framu od framu frame.
#endif

426
VIDEO/MGIFEBLD.C Normal file
View file

@ -0,0 +1,426 @@
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <malloc.h>
#include <memman.h>
#include <event.h>
#include <bmouse.h>
#include <gui.h>
#include <basicobj.h>
#include <zvuk.h>
#include <bgraph.h>
#include <mgifmem.h>
#include <strlite.h>
#include <strlists.h>
#include "lzw.h"
#include "mgifeobj.h"
#include "mgifedit.h"
#include "mgifeact.h"
#include "mgifebld.h"
#include <wav.h>
#include <time.h>
static short **frame_table;
static char work_buff[100000];
static int last1=0;
static int last2=0;
static int last_time=0;
int frames_build=0;
int amplifikace=0;
typedef struct tsample
{
FILE *fs;
int start_data;
int length;
int pos;
long loop_start;
long loop_end;
char running;
char bit16;
char stereo;
}TSAMPLE;
static TSAMPLE sample;
static void Create_table_16(short *ampl_table,int difftype)
{
int a,c,d,e;
float b;
d=-1;e=0;
for(a=0;a<128;a++)
{
b=(a/128.0);
switch (difftype)
{
case 1:b=(b*32768.0);break;
case 2:b=(b*b*32768.0);break;
case 3:b=(b*b*b*32768.0);break;
case 4:b=(b*b*b*b*32768.0);break;
case 5:b=(b*b*b*b*b*32768.0);break;
}
c=(int)b;
if (c==d) e++;
d=c;c+=e;
ampl_table[128+a]=c;
ampl_table[128-a]=-c;
}
}
static int find_index(short *ampl_table,int value)
{
int i;
if (value==0) return 128;
if (value>0)
{
for(i=128;i<256;i++)
if (ampl_table[i]>value) return i-1;
return 255;
}
else
{
for(i=128;i>=0;i--)
if (ampl_table[i]<value) return i+1;
return 1;
}
}
static void compress_buffer_stereo(short *ampl_table,short *source,int size)
{
int i;
int l1=last1,l2=last2;
int val;
char indx;
for(i=0;i<size;i++)
{
if (i & 1)
{
val=source[i];
indx=find_index(ampl_table,val-l1);
l1+=ampl_table[indx];
if (l1>32768 || l1<-32768) crash("Building error (owerflow)");
work_buff[i]=indx;
}
else
{
val=source[i];
indx=find_index(ampl_table,val-l2);
l2+=ampl_table[indx];
if (l2>32768 || l2<-32768) crash("Building error (owerflow)");
work_buff[i]=indx;
}
}
last1=l1;last2=l2;
}
static char save_buffer(FILE *f,int seekp,short *buffer,int size)
{
compress_buffer_stereo(mgf_header.ampl_table,buffer,size);
fseek(f,seekp,SEEK_SET);
return fwrite(work_buff,1,size,f)!=size;
}
static char save_all()
{
int i,c=0;
FRAME_DEFS_T *fd;
FILE *f;
f=fopen(mgif_filename,"rb+");
if (f==NULL) return 1;
fwrite(&mgf_header,1,sizeof(mgf_header),f);
for(i=0,fd=mgf_frames;i<total_frames;i++,fd++) if (frame_table[i]!=NULL)
{
last1=(short)(fd->vol_save & 0xffff);
last2=(short)(fd->vol_save>>16);
if (save_buffer(f,fd->sound_start,frame_table[i],fd->track_size))
{
fclose(f);
return 1;
}
c_set_value(0,10,(c++)*100/frames_build);
do_events();if (exit_wait) break;
fd->changed=0;
free(frame_table[i]);frame_table[i]=NULL;
if (i<total_frames-1) mgf_frames[i+1].vol_save=(last1 & 0xffff) | (last2<<16);
}
fclose(f);
return 0;
}
static void fill_frame_table(int from_frame)
{
int i;void *p;
frames_build=0;
if (frame_table==NULL) frame_table=NewArr(short *,total_frames);
memset(frame_table,NULL,total_frames);
for(i=from_frame;i<total_frames;i++) if (mgf_frames[i].changed)
{
int s=mgf_frames[i].track_size*2;
p=_nmalloc(s);
frame_table[i]=p;
if (p==NULL) break;
memset(p,0,s);
frames_build++;
}
}
static char register_sample(char *sample_name,long loop_start,long loop_end)
{
FILE *f;
T_WAVE *head;
f=sample.fs=fopen(sample_name,"rb");
if (f==NULL) return 1;
if (find_chunk(f,WAV_FMT)!=-1)
{
head=(T_WAVE *)getmem(get_chunk_size(f));
if (read_chunk(f,head) && (sample.start_data=find_chunk(f,WAV_DATA))!=-1)
{
sample.length=get_chunk_size(f);
sample.fs=f;
sample.running=0;
sample.bit16=((head->bps/head->freq)/head->chans)==2;
sample.stereo=(head->chans==2);
sample.pos=0;
if (loop_start==-1) loop_start=loop_end=sample.length;
sample.loop_start=loop_start;
sample.loop_end=loop_end;
free(head);
return 0;
}
free(head);
}
fclose(f);
return 1;
}
static void skip_frame(int frm_len) //v puvodni velikosti (16-bit stereo)
{
if (!sample.bit16) frm_len/=2;
if (!sample.stereo) frm_len/=2;
sample.pos+=frm_len;
if (sample.loop_start<sample.loop_end)
while (sample.pos>=sample.loop_end) sample.pos-=sample.loop_end-sample.loop_start;
if (sample.pos>=sample.length) sample.running=0;
}
static char build_sound(int frm_len,short *buffer,word vol1,word vol2)
{
short val1,val2;
int rozsah,pos;
char vol1l,vol2l,vol1r,vol2r;
int ipos=ftell(sample.fs)-sample.start_data;
vol1l=vol1 & 0xff;vol2l=vol2 & 0xff;
vol1r=vol1>>8;vol2r=vol2>>8;
rozsah=frm_len/4;
pos=0;
fseek(sample.fs,sample.pos+sample.start_data,SEEK_SET);
while (frm_len>0)
{
short i,*j=&val1;
if (ipos>sample.pos) fseek(sample.fs,sample.pos+sample.start_data,SEEK_SET);
ipos=sample.pos;
for(i=0;i<2;i++)
{
if (sample.bit16) fread(j,1,2,sample.fs);
else
{
fread(j,1,1,sample.fs);*j<<=8;
*j^=0x8000;
}
if (!sample.stereo)
{
val2=val1;break;
}
else
j=&val2;
}
if (ferror(sample.fs)) return 1;
val1=val1*(vol1l+(vol2l-vol1l)*pos/rozsah)/256;
val1>>=amplifikace;
val2=val2*(vol1r+(vol2r-vol1r)*pos/rozsah)/256;
val2>>=amplifikace;
skip_frame(4);
if (*buffer+val1>32767) *buffer++=32767;
else if (*buffer+val1<-32768) *buffer++=-32768;
else *buffer+++=val1;
if (*buffer+val2>32767) *buffer++=32767;
else if (*buffer+val2<-32768) *buffer++=-32768;
else *buffer+++=val2;
pos++;
frm_len-=4;
if (!sample.running) break;
}
return 0;
}
static char build_frame_sound(int frame,int sample)
{
TRACK_DATA_T z1l,z1r,z2l,z2r;
if (frame_table[frame]==NULL)
{
skip_frame(mgf_frames[frame].track_size*2);
}
else
{
get_vpoint(smp_prg[sample].levy,frame,&z1l);
get_vpoint(smp_prg[sample].pravy,frame,&z1r);
get_vpoint(smp_prg[sample].levy,frame+1,&z2l);
get_vpoint(smp_prg[sample].pravy,frame+1,&z2r);
if (z1l.vpoint1 || z2l.vpoint1 || z1r.vpoint1 || z2r.vpoint1)
return build_sound(mgf_frames[frame].track_size*2,
frame_table[frame],
(z1r.vpoint1<<8)+z1l.vpoint1,
(z2r.vpoint1<<8)+z2l.vpoint1);
else
skip_frame(mgf_frames[frame].track_size*2);
}
return 0;
}
char build_one_sample(int smp)
{
int d=0;
int i;
int p,c,*pl;
if (smp_prg[smp].muted) return 0;
if (register_sample(smp_prg[smp].sample_name,
smp_prg[smp].loop_start,
smp_prg[smp].loop_end)) return 1;
pl=smp_prg[smp].starts;
c=smp_prg[smp].starts_count;
for(i=0;i<total_frames;i++)
{
if (frame_table[i]!=NULL)
{
if ((d & 0x1f)==0) c_set_value(0,10,d*100/frames_build);
d++;
}
if (exit_wait) break;
for(p=0;p<c;p++)
if (pl[p]==i)
{
sample.running=1;
sample.pos=0;
break;
}
else
if (pl[i]>i) break;
if (sample.running)
{
build_frame_sound(i,smp);
do_events();
}
}
fclose(sample.fs);
return 0;
}
static void destroy_all()
{
int i;
for(i=0;i<total_frames;i++) if (frame_table[i]!=NULL)
{
free(frame_table[i]);frame_table[i]=NULL;
}
}
char build_solo(int smp)
{
Create_table_16(&mgf_header.ampl_table,3);
fill_frame_table(0);
if (build_one_sample(smp))
{
destroy_all();
return 1;
}
save_all();
return 0;
}
static void error_message(int smp)
{
char *c;
char *msg="Nastala chyba p©i pr ci se stopou:";
if (smp_prg[smp].user_name!=NULL)
{
concat(c,msg,smp_prg[smp].user_name);
}
else
{
concat(c,msg,smp_prg[smp].sample_name);
}
msg_box(PRG_HEADER,'\x1',msg,"Pokra‡ovat",NULL);
}
char build_all_samples()
{
int i;
clock_t start_time,end_time;
start_time=clock();
Create_table_16(&mgf_header.ampl_table,3);
fill_frame_table(0);
for(i=0;i<samples_total;i++)
{
set_value(0,20,smp_prg[i].sample_name);
if (build_one_sample(i))
error_message(i);
do_events();
if (exit_wait)
{
exit_wait=0;
destroy_all();
return 0;
}
}
set_value(0,20,"Ukl d m zvukovou stopu...");
save_all();
destroy_all();
exit_wait=0;
end_time=clock();
last_time=(end_time-start_time)/CLOCKS_PER_SEC;
return 0;
}
void set_changed_range(int fr1,int fr2)
{
if (fr2>=total_frames) fr2=total_frames-1;
for(;fr1<=fr2;fr1++) mgf_frames[fr1].changed=1;
}
void set_changed_track(TRACK_DATA_T *ti)
{
int fr=0;
while (ti!=NULL)
{
if (ti->changed) set_changed_range(fr,fr+ti->time);
fr+=ti->time;
ti->changed=0;
ti=ti->next;
}
}
int get_building_time()
{
return last_time;
}

9
VIDEO/MGIFEBLD.H Normal file
View file

@ -0,0 +1,9 @@
extern int amplifikace;
extern int frames_build;
char build_solo(int smp);
char build_all_samples();
void set_changed_range(int fr1,int fr2);
void set_changed_track(TRACK_DATA_T *ti);
int get_building_time();

905
VIDEO/MGIFEDIT.C Normal file
View file

@ -0,0 +1,905 @@
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <malloc.h>
#include <memman.h>
#include <event.h>
#include <bmouse.h>
#include <gui.h>
#include <basicobj.h>
#include <zvuk.h>
#include <bgraph.h>
#include "lzw.h"
#include "mgifeobj.h"
#include "mgifeact.h"
#include "mgifedit.h"
#include "mgifebld.h"
#include <strlists.h>
#include <strlite.h>
#include <direct.h>
#include <mgfplay.h>
#include <wav.h>
void *vga_font=&boldcz;
void *icones=&ikones;
void *ms_cur=&sipka;
word icone_color[7]={0x2108,0x7fff,0x000f,0x4210,0x6f7b};
int win_preview;
int win_program=-1;
int cur_track=-1;
int win_control;
TSTR_LIST smp_list;
char last_path[256]="";
char *prj_name;
static void grinit(void)
{
initmode32();
register_ms_cursor(ms_cur);
init_mysky();
// hranice_mysky(0,0,639,479);
update_mysky();
schovej_mysku();
bar(0,0,639,479);
showview(0,0,0,0);
}
void init_sound()
{
int a,b,c,d;
if (sound_detect(&a,&b,&c,&d))
{
puts("No sound device found");
a=DEV_NOSOUND;
}
set_mixing_device(a,22000,b,c,d);
}
static void f10exit()
{
int c;
do
{
c=*(int*)task_wait_event(E_KEYBOARD);
if ((c & 0xff)==0 && (c>>8)=='D') terminate();
if ((c & 0xff)==0 && (c>>8)=='C')
{
done_mysky();
closemode();
grinit();
redraw_desktop();
schovej_mysku();
zobraz_mysku();
}
}
while (1);
}
void initialization(void)
{
init_sound();
grinit();
init_events();
install_gui();
zobraz_mysku();
update_mysky();
add_task(1024,f10exit);
redraw_desktop();do_events();
msg_box_font=vga_font;
msg_icn_font=icones;
getcwd(last_path,255);
}
long def_window(word xs,word ys,char *name)
{
word x=0,y=0;
WINDOW *p;
CTL3D ctl;
FC_TABLE fc;
long q;
if (waktual!=NULL)
{
x=waktual->x;
y=waktual->y;
}
highlight(&ctl,WINCOLOR);
ctl.bsize=2;ctl.ctldef=0;
x+=20;y+=20;
memcpy(fc,flat_color(0x7fe0),sizeof(FC_TABLE));
fc[0]=0x0000;
if (x+xs>MAX_X-2) x=MAX_X-2-xs;
if (y+ys>MAX_Y-2) y=MAX_Y-2-ys;
p=create_window(x,y,xs,ys,WINCOLOR,&ctl);
q=desktop_add_window(p);
define(0,2,2,xs-5-20*(xs>=70),14,0,win_label,name);
ctl.bsize=1;ctl.ctldef=1;
o_end->autoresizex=1;
property(&ctl,vga_font,&fc,LABELCOLOR);
if (xs>=70)
{
define(1,1,1,19,16,1,button,"\x0f");
property(NULL,icones,&icone_color,WINCOLOR);on_change(close_current);
}
return q;
}
int def_dialoge(word x,word y,word xs, word ys, char *name,char modal)
{
CTL3D ctl;
FC_TABLE fc;
WINDOW *p;
int i;
memcpy(fc,flat_color(0x7fe0),sizeof(FC_TABLE));
memcpy(&ctl,def_border(2,WINCOLOR),sizeof(CTL3D));
p=create_window(x,y,xs,ys,WINCOLOR,&ctl);
i=desktop_add_window(p);
if (modal) set_window_modal();
ctl.bsize=1;ctl.ctldef=1;
define(0,1,1,xs-2,14,0,win_label,name);
o_end->autoresizex=1;
property(&ctl,vga_font,&fc,LABELCOLOR);
return i;
}
static void display_progress(void)
{
def_dialoge(10,300,620,80,"Na‡¡t m informace o filmu...",1);
define(10,10,20,600,30,0,done_bar,100);
property(def_border(3,WINCOLOR),NULL,flat_color(0x2e0),WINCOLOR);
define(30,5,5,80,20,2,button,"Konec");on_change(terminate);
property(def_border(1,0),vga_font,flat_color(0),BUTTONCOLOR);
c_default(0);
redraw_window();
exit_wait=0;
}
static char show_progress(int perc)
{
c_set_value(0,10,perc);
do_events();
return exit_wait;
}
static void done_progress(void)
{
if (exit_wait)
{
shutdown();
puts("Program aborted by user...");
exit(0);
}
exit_wait=0;
close_current();
redraw_desktop();
}
void show_frame(int frame)
{
static int last_task=0;
if (last_task) term_task(last_task);
while (last_task!=0) task_sleep(NULL);
if (frame>=0) last_task=add_task(32768,build_frame,frame,&last_task);
}
int delay_task=0;
int delay_task_counter=0;
void delayed_redraw() //task!
{
for(delay_task_counter=0;delay_task_counter<5;delay_task_counter++) task_wait_event(E_TIMER);
delay_task=0;
redraw_desktop();
}
static void change_frame_pos()
{
int frame;
frame=f_get_value(win_preview,20);
if (find_window(win_program)!=NULL)
{
set_value(win_program,10,&frame);
set_value(win_program,20,&frame);
set_value(win_program,30,&frame);
if (!delay_task) delay_task=add_task(1024,delayed_redraw);
else delay_task_counter=0;
}
show_frame(frame);
}
void init_desktop(void)
{
FC_TABLE cl;
cl[0]=0;cl[1]=0x610;
win_preview=def_dialoge(10,10,324,228,"Preview",0);
define(5,1,1,14,14,1,color_box);c_default(LABELCOLOR);
define(10,2,20,320,180,0,pic_viewer);c_default(0);
define(20,26,4,271,17,3,scroll_bar_h,0,total_frames-1,total_frames/16,0x0200);
property(def_border(3,WINCOLOR),NULL,NULL,WINCOLOR);c_default(0);on_change(change_frame_pos);
define(21,2,4,21,19,2,scroll_button,1,100,"\x1c");
property(NULL,icones,&cl,WINCOLOR);on_change(scroll_support);
define(22,2,4,21,19,3,scroll_button,-1,-100,"\x1d");
property(NULL,icones,&cl,WINCOLOR);on_change(scroll_support);
redraw_desktop();
show_frame(0);
}
void shutdown()
{
done_mysky();
closemode();
}
static void init_editor()
{
char *chyba;
display_progress();
switch(examine_mgif_file(show_progress))
{
case EX_NOT_FOUND:chyba="MGIF soubor nenalezen!";break;
case EX_NO_SOUND:chyba="Film nem  zvukovou stopu. Sestav jej se zvukem.";break;
case EX_READ_ERROR:chyba="Chyba p©i ‡ten¡. Film je mon  po¨kozen";break;
case EX_SOUND_ERROR:chyba="Nekonzistentn¡ zvukov  stopa!";break;
default:chyba=NULL;
}
if (chyba!=NULL)
{
msg_box(PRG_HEADER,'\x1',chyba,"Stop",NULL);
shutdown();
abort();
}
done_progress();
}
static int step_vpoint=1;
static void change_vpoint()
{
TRACK_DATA_T **p,z;
int id=o_aktual->id;
int frame;
int m;
if (id>100)
{
p=&smp_prg[cur_track].pravy;
id-=100;
}
else
p=&smp_prg[cur_track].levy;
frame=f_get_value(win_preview,20);
get_vpoint(*p,frame,&z);
m=z.vpoint1;
switch(id)
{
case 50:m-=step_vpoint>>3;if (m<0) m=0; set_vpoint(p,frame,m,m);step_vpoint++;break;
case 40:m+=step_vpoint>>3;if (m>255) m=255; set_vpoint(p,frame,m,m);step_vpoint++;break;
case 60:delete_vpoint(p,frame);break;
case 70:if (z.next!=NULL) set_vpoint(p,frame,z.next->vpoint1,z.next->vpoint1);break;
case 80:change_vpoint_spacing(*p,frame,step_vpoint>>3);step_vpoint++;break;
case 90:change_vpoint_spacing(*p,frame,-(step_vpoint>>3));step_vpoint++;break;
}
redraw_window();
}
static void step_clear(EVENT_MSG *msg)
{
if (msg->msg==E_LOST_FOCUS)
{
step_vpoint=8;
return;
}
if (msg->msg==E_MOUSE)
{
MS_EVENT *ms;
ms=get_mouse(msg);
if (ms->event_type & (0x4|0x8)) step_vpoint=8;
}
}
static void toggle_restart()
{
int *p;
int i,c;
int frame;
frame=f_get_value(win_preview,20);
c=smp_prg[cur_track].starts_count;
p=smp_prg[cur_track].starts;
for(i=0;i<c;i++) if (frame==p[i]) break;
if (i==c) add_restart(smp_prg+cur_track,frame);
else delete_restart(smp_prg+cur_track,frame);
compare_vol_table(smp_prg+cur_track);
set_vol_table_nul();
compare_vol_table(smp_prg+cur_track);
redraw_window();
}
static void max_min_mid_align()
{
int frame;
TRACK_DATA_T z1,**p1;
TRACK_DATA_T z2,**p2;
int vol1,vol2,vol;
frame=f_get_value(win_preview,20);
p1=&smp_prg[cur_track].levy;
p2=&smp_prg[cur_track].pravy;
get_vpoint(*p1,frame,&z1);
get_vpoint(*p2,frame,&z2);
vol1=z1.vpoint1;
vol2=z2.vpoint1;
switch (o_aktual->id)
{
case 210:vol=max(vol1,vol2);break;
case 220:vol=min(vol1,vol2);break;
case 230:vol=(vol1+vol2)/2;break;
case 240:vol=vol2;break;
case 250:vol=vol1;break;
}
set_vpoint(p1,frame,vol,vol);
set_vpoint(p2,frame,vol,vol);
redraw_window();
}
static void change_frame_clk1()
{
int fr;
fr=f_get_value(0,o_aktual->id);
c_set_value(win_preview,20,fr);
c_set_value(win_program,10,fr);
c_set_value(win_program,20,fr);
c_set_value(win_program,30,fr);
show_frame(fr);
}
static void mute_channel()
{
char c;
int i;
c=f_get_value(0,260);
for(i=10;i<260;i++)set_enable(0,i,!c);
if (smp_prg[cur_track].muted!=c)
{
compare_vol_table(smp_prg+cur_track);
set_vol_table_nul();
compare_vol_table(smp_prg+cur_track);
smp_prg[cur_track].muted=c;
}
}
void open_program_window(int track)
{
FC_TABLE cl1,cl2;
CTL3D *cl;
int i;
int frame;
frame=f_get_value(win_preview,20);
if (track>=samples_total) track=-1;
if (cur_track!=track)
{
WINDOW *w;
w=find_window(win_program);if (w!=NULL) close_window(w);
if (cur_track>=0 && cur_track<samples_total)
compare_vol_table(smp_prg+cur_track);
cur_track=track;
if (cur_track>=0 && cur_track<samples_total)
read_vol_table(smp_prg+cur_track);
}
else return;
if (track<0) return;
cl1[0]=0x8000;cl1[1]=0xf;
memcpy(cl2,flat_color(0),sizeof(cl2));
win_program=def_dialoge(10,250,620,220,smp_prg[track].sample_name,0);
define(10,10,20,500,70,0,track_view,&smp_prg[track].levy);on_change(change_frame_clk1);
property(def_border(5,WINCOLOR),NULL,NULL,WINCOLOR);c_default(frame);
define(20,10,120,500,70,0,track_view,&smp_prg[track].pravy);on_change(change_frame_clk1);
property(def_border(5,WINCOLOR),NULL,NULL,WINCOLOR);c_default(frame);
define(30,10,95,500,20,0,starts_view,smp_prg+track);
property(def_border(5,WINCOLOR),NULL,NULL,WINCOLOR);c_default(frame);
for(i=0;i<=100;i+=100)
{
int y=i;
define(40+i,85,20+y,20,35,1,scroll_button,-1,0,"\x1e");
property(NULL,icones,&cl1,WINCOLOR);on_change(change_vpoint);on_event(step_clear);
define(50+i,85,56+y,20,35,1,scroll_button,1,255,"\x1f");
property(NULL,icones,&cl1,WINCOLOR);on_change(change_vpoint);on_event(step_clear);
define(60+i,10,20+y,20,70,1,button,"X");on_change(change_vpoint);
property(NULL,vga_font,cl2,WINCOLOR);
define(70+i,32,20+y,50,20,1,button,"+ÄÄÄ+");on_change(change_vpoint);
property(NULL,vga_font,cl2,WINCOLOR);
define(80+i,32,45+y,50,20,1,scroll_button,-1,0,"+--+");
property(NULL,vga_font,&cl2,WINCOLOR);on_change(change_vpoint);on_event(step_clear);
define(90+i,32,70+y,50,20,1,scroll_button,1,255,"+--+");
property(NULL,vga_font,&cl2,WINCOLOR);on_change(change_vpoint);on_event(step_clear);
}
define(200,10,95,95,20,1,button,"(re)Start");property(NULL,vga_font,&cl2,WINCOLOR);
on_change(toggle_restart);
cl=def_border(1,0);
define(210,10,5,80,20,3,button,"Max");property(cl,vga_font,&cl2,BUTTONCOLOR);on_change(max_min_mid_align);
define(220,100,5,80,20,3,button,"Min");property(cl,vga_font,&cl2,BUTTONCOLOR);on_change(max_min_mid_align);
define(230,190,5,80,20,3,button,"St©ed");property(cl,vga_font,&cl2,BUTTONCOLOR);on_change(max_min_mid_align);
define(240,280,5,80,20,3,button,"Jako doln¡");property(cl,vga_font,&cl2,BUTTONCOLOR);on_change(max_min_mid_align);
define(250,370,5,80,20,3,button,"Jako horn¡");property(cl,vga_font,&cl2,BUTTONCOLOR);on_change(max_min_mid_align);
define(260,10,10,80,10,2,check_box,"Vypnut");on_change(mute_channel);c_default(smp_prg[cur_track].muted);
redraw_window();
mute_channel();
}
static void change_dir()
{
int i;
char *mask;
TSTR_LIST ls;
get_value(0,20,last_path);
c_set_value(0,9,0);
send_message(E_GUI,9,E_CONTROL,2);
i=strlen(last_path);
strupr(last_path);
if (i!=0 && last_path[i-1]!='\\')
{
strcat(last_path,"\\");
set_value(0,20,last_path);
}
concat(mask,last_path,"*.WAV");
send_message(E_GUI,9,E_CONTROL,0,&ls);
release_list(ls);
ls=read_directory(mask,DIR_NAMES,_A_NORMAL);
if (ls==NULL)
{
ls=create_list(2);
str_add(&ls,"<nic>");
}
send_message(E_GUI,9,E_CONTROL,1,ls);
}
static void dopln_jmeno_samplu()
{
char *name,*c;
TSTR_LIST ls;
int i;
FILE *f;
send_message(E_GUI,9,E_CONTROL,0,&ls);
i=f_get_value(0,9);
if (ls[i]==NULL) return;
c=ls[i];
if (!strcmp(c,"<nic>")) return;
concat(name,last_path,c);
set_value(0,30,name);
f=fopen(name,"rb");
if (f!=NULL)
{
if (find_chunk(f,WAV_DATA)!=-1)
{
char d[50];
set_value(0,60,itoa(get_chunk_size(f),d,10));
}
fclose(f);
}
}
void new_edit_sample(int track)
{
TSTR_LIST dir;
CTL3D b1,b2,b3;
char *c,empty[]="";
char num[200];
memcpy(&b1,def_border(1,0),sizeof(CTL3D));
memcpy(&b2,def_border(5,WINCOLOR),sizeof(CTL3D));
memcpy(&b3,def_border(6,WINCOLOR),sizeof(CTL3D));
def_dialoge(20,140,600,200,"Vlo nov˜ zvuk",1);
dir=create_list(2);str_add(&dir,"<wait>");
define(9,10,20,120,166,0,listbox,dir,0x7fff,0);on_change(dopln_jmeno_samplu);
property(&b3,NULL,NULL,WINCOLOR);c_default(0);
define(10,137,40,19,127,0,scroll_bar_v,0,10,1,0x0200);
property(&b2,NULL,NULL,WINCOLOR);
define(11,136,20,21,17,0,scroll_button,-1,0,"\x1e");
property(NULL,icones,NULL,WINCOLOR);on_change(scroll_support);
define(12,136,170,21,17,0,scroll_button,1,10,"\x1f");
property(NULL,icones,NULL,WINCOLOR);on_change(scroll_support);
define(20,170,20,420,12,0,input_line,255);set_default(last_path);on_exit(change_dir);
property(&b3,vga_font,NULL,WINCOLOR);
define(-1,170,35,1,1,0,label,"Cesta a jmno zvuku");
define(-1,170,65,1,1,0,label,"Jmno stopy (voliteln)");
define(-1,170,95,1,1,0,label,"Za‡ tek opakov n¡ (-1 vyp)");
define(-1,170,125,1,1,0,label,"Konec opakov ");
c=(smp_prg[track].sample_name);if (c==NULL) c=empty;
define(30,170,50,420,12,0,input_line,255);set_default(c);
property(&b3,vga_font,NULL,WINCOLOR);
c=(smp_prg[track].user_name);if (c==NULL) c=empty;
define(40,170,80,220,12,0,input_line,255);set_default(c);
property(&b3,vga_font,NULL,WINCOLOR);
define(50,290,110,100,12,0,input_line,199);set_default(itoa(smp_prg[track].loop_start,num,10));
property(&b3,vga_font,NULL,WINCOLOR);
define(60,290,140,100,12,0,input_line,199);set_default(itoa(smp_prg[track].loop_end,num,10));
property(&b3,vga_font,NULL,WINCOLOR);
define(100,10,10,80,20,2,button,"Storno");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(terminate);
define(110,10,35,80,20,2,button,"Ok");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(terminate);
define(120,10,70,38,20,2,button,"");property(&b1,vga_font,NULL,BUTTONCOLOR);
define(130,52,70,38,20,2,button,"");property(&b1,vga_font,NULL,BUTTONCOLOR);
redraw_window();
change_dir();
escape();
if (o_aktual->id==110)
{
char s[256];
TRACK_INFO_T *t=smp_prg+track;
get_value(0,30,s);free(t->sample_name);t->sample_name=NewArr(char,strlen(s)+1);
strcpy(t->sample_name,s);
get_value(0,40,s);free(t->user_name);
if (s[0]!=0)
{
t->user_name=NewArr(char,strlen(s)+1);
strcpy(t->user_name,s);
}
else t->user_name=NULL;
get_value(0,50,s);t->loop_start=atoi(s);
get_value(0,60,s);t->loop_end=atoi(s);
}
close_current();
}
static void select_sample()
{
int i;
i=f_get_value(0,9);
open_program_window(i);
}
static void update_sample_list()
{
TSTR_LIST ls;
int i;
char p;
send_message(E_GUI,9,E_CONTROL,0,&ls);
build_sample_list(&ls);
send_message(E_GUI,9,E_CONTROL,1,ls);
i=f_get_value(0,9);
if (i>=samples_total) i=samples_total-1;
if (i<0) i=0;
c_set_value(0,9,i);
p=samples_total!=0;
set_enable(0,30,p);set_enable(0,40,p);set_enable(0,50,p);
run_background(select_sample);
}
static void new_sample()
{
int track;
track=add_sample("");
open_program_window(-1);
select_sample();
new_edit_sample(track);
select_window(win_control);
if (smp_prg[track].sample_name[0]==0) remove_sample(track);
else
{
c_set_value(0,9,track);
set_vol_table_nul();
compare_vol_table(smp_prg+track);
}
update_sample_list();
}
static void edit_sample()
{
int i;
i=f_get_value(0,9);
if (i>=samples_total || i<0) return;
new_edit_sample(i);
compare_vol_table(smp_prg+cur_track);
set_vol_table_nul();
compare_vol_table(smp_prg+cur_track);
open_program_window(-1);
update_sample_list();
}
static void delete_sample()
{
int i;
i=f_get_value(0,9);
if (i>=samples_total || i<0) return;
if (msg_box("Ot zka?",'\x2',"Odstranit zvuk?","Ano","Ne",NULL)==2) return;
open_program_window(-1);
remove_sample(i);
update_sample_list();
}
static void duplic_sample()
{
int track;
int i;
TRACK_INFO_T *t1,*t2;
i=f_get_value(0,9);
if (i>=samples_total || i<0) return;
t1=smp_prg+i;
track=add_sample(t1->sample_name);
open_program_window(-1);
t1=smp_prg+i;
t2=smp_prg+track;
if (t1->user_name!=NULL)
{
t2->user_name=NewArr(char,strlen(t1->user_name)+1);
strcpy(t2->user_name,t1->user_name);
}
else t2->user_name=NULL;
t1->loop_start=t2->loop_start;
t1->loop_end=t2->loop_end;
c_set_value(0,9,track);
send_message(E_GUI,9,E_CONTROL,2);
update_sample_list();
}
static void prehrat_cele()
{
show_frame(-1);
def_dialoge(2,42,635,378,"P©ehr t cel",1);
redraw_window();
curcolor=0;
start_mixing();
play_animation(mgif_filename,SMD_HICOLOR,60,1);
stop_mixing();
close_current();
}
static void stop_preview_clk()
{
stop_preview();
}
static void prehrat_preview()
{
OBJREC *o;
WINDOW *w;
int x,y;
w=find_window(win_preview);
o=find_object(w,10);
show_frame(-1);
x=o->locx+320+4;
y=o->locy+180+4;
if (x>500) x=2;if (y>400) y=2;
def_dialoge(x,y,100,80,"N hled",1);
define(10,10,25,80,30,0,button,"STOP");
property(def_border(1,0),vga_font,NULL,BUTTONCOLOR);on_change(stop_preview_clk);
redraw_window();
preview_block(f_get_value(win_preview,20),o->locx,o->locy);
close_current();
}
static void make()
{
if (cur_track>=0 && cur_track<samples_total)
compare_vol_table(smp_prg+cur_track);
def_dialoge(10,300,620,80,"Sestavuji...",1);
define(10,10,20,600,30,0,done_bar,100);c_default(0);
property(def_border(3,WINCOLOR),NULL,flat_color(0x2e0),WINCOLOR);
define(20,5,5,480,12,3,input_line,100);set_default("Ukl d m projekt....");
define(30,5,5,80,20,2,button,"Stop");on_change(terminate);
property(def_border(1,0),vga_font,NULL,BUTTONCOLOR);
redraw_window();
save_project(prj_name);
build_all_samples();
close_current();
}
static void build()
{
int i;
if (msg_box(PRG_HEADER,'\x2',"Chce¨ spustit REBUILD filmu? Tato funkce sestav¡ CELOU zvukovou stopu, co me zabrat dost ‡asu","Ano","Ne",NULL)==2) return;
for(i=0;i<total_frames;i++)
mgf_frames[i].changed=1;
make();
}
static void exit_prog()
{
int i;
i=msg_box("Exit",'\x2',"Uloit projekt p©ed ukon‡en¡m programu?","Ano","Ne","Storno",NULL);
switch (i)
{
case 3:return;
case 1:save_project(prj_name);
case 2:terminate();
}
}
static int calcul_build_memory()
{
int suma=0;
int i;
for(i=0;i<total_frames;i++) suma+=mgf_frames[i].track_size*2;
suma/=1024;
return suma;
}
static void info()
{
static char *texty[]=
{
"Film:",
"Project:",
"Celkem sn¡mk:",
"Pr zdn˜ch sn¡mk:",
"Vyuit  pamˆŸ(KB):",
"Sestavovac¡ pamˆŸ(KB):",
"Stop:",
"Sestaveno sn¡mk:",
"Cas sestaven¡:",
};
char str[200];char *c;
int i;
def_dialoge(150,100,340,240,"Info",1);
for(i=0;i<9;i++)
define(-10,180-text_width(texty[i]),20+i*15,1,1,0,label,texty[i]);
define(-10,50,170,1,1,0,label,"Amplifikace:");
c=strrchr(mgif_filename,'\\');if (c==NULL)c=mgif_filename;else c++;
define(-10,190,20,1,1,0,label,c);
c=strrchr(prj_name,'\\');if (c==NULL)c=prj_name;else c++;
define(-10,190,35,1,1,0,label,c);
define(-10,190,50,1,1,0,label,itoa(total_frames,str,10));
define(-10,190,65,1,1,0,label,itoa(frame_shift,str,10));
define(-10,190,80,1,1,0,label,itoa(total_frames*sizeof(FRAME_DEFS_T)/1024,str,10));
define(-10,190,95,1,1,0,label,itoa(calcul_build_memory(),str,10));
define(-10,190,110,1,1,0,label,itoa(samples_total,str,10));
define(-10,190,125,1,1,0,label,itoa(frames_build,str,10));
i=get_building_time(); sprintf(str,"%02d:%02d",i/60,i%60);
define(-10,190,140,1,1,0,label,str);
define(10,190,170,40,60,0,radio_butts,5,
"1/1",
"1/2",
"1/4",
"1/8",
"1/16");c_default(amplifikace);
define(100,5,5,60,20,2,button,"Ok");on_change(terminate);
redraw_window();
escape();
if (amplifikace!=f_get_value(0,10))
{
msg_box(PRG_HEADER,'\x1',"Aby tato zmˆna mˆla spr vn˜ efekt, mus¡¨ provst BUILD!","Ok",NULL);
amplifikace=f_get_value(0,10);
}
close_current();
}
char how_frames(char *prompt,int *value)
{
char buffer[20];
CTL3D b1;
def_dialoge(200,200,200,100,"GINSERT/GDELETE",1);
memcpy(&b1,def_border(1,0),sizeof(CTL3D));
define(10,5,20,1,1,0,label,prompt);
define(20,10,35,60,12,1,input_line,10);set_default(itoa(*value,buffer,10));
property(def_border(5,WINCOLOR),NULL,NULL,0x7fff);
define(30,5,5,80,20,2,button,"Ok");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(terminate);
define(40,90,5,80,20,2,button,"Zru¨it");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(terminate);
redraw_window();
chyba:
escape();
if (o_aktual->id==30)
{
get_value(0,20,buffer);
if (sscanf(buffer,"%d",value)!=1)
{
msg_box(PRG_HEADER,'\x1',"To mus¡ b˜t ‡¡slo!","Ok",NULL);
goto chyba;
}
close_current();
return 1;
}
close_current();
return 0;
}
static void ginsert()
{
int v;
int frame;
frame=f_get_value(win_preview,20);
v=get_inserted_frames(frame);
if (how_frames("Kolik bylo vloeno?",&v)==0) return;
insert_global(frame,v);
redraw_desktop();
}
static void gdelete()
{
int v;
int frame;
frame=f_get_value(win_preview,20);
v=get_deleted_frames();
if (how_frames("Kolik bylo vymaz no?",&v)==0) return;
delete_global(frame,v);
redraw_desktop();
}
void control_window()
{
CTL3D b1,b2,b3;
char p;
memcpy(&b1,def_border(1,0),sizeof(CTL3D));
memcpy(&b2,def_border(5,WINCOLOR),sizeof(CTL3D));
memcpy(&b3,def_border(6,WINCOLOR),sizeof(CTL3D));
default_font=vga_font;
memcpy(f_default,flat_color(0x0000),sizeof(charcolors));
win_control=def_dialoge(350,10,280,228,PRG_HEADER,0);
build_sample_list(&smp_list);
define(9,10,20,100,196,0,listbox,smp_list,0x7fff,0);on_change(select_sample);
property(&b3,NULL,NULL,WINCOLOR);c_default(-1);
define(10,117,40,19,157,0,scroll_bar_v,0,10,1,0x0200);
property(&b2,NULL,NULL,WINCOLOR);
define(11,116,20,21,17,0,scroll_button,-1,0,"\x1e");
property(NULL,icones,NULL,WINCOLOR);on_change(scroll_support);
define(12,116,200,21,17,0,scroll_button,1,10,"\x1f");
property(NULL,icones,NULL,WINCOLOR);on_change(scroll_support);
define(20,140,20,65,20,0,button,"Nov˜");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(new_sample);
define(30,210,20,65,20,0,button,"Odstra¤");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(delete_sample);
define(40,140,45,65,20,0,button,"Oprav");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(edit_sample);
define(50,210,45,65,20,0,button,"Duplikuj");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(duplic_sample);
define(60,140,120,65,20,0,button,"P©ehr t");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(prehrat_cele);
define(70,210,120,65,20,0,button,"N hled");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(prehrat_preview);
define(80,140,145,65,20,0,button,"Make");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(make);
define(90,210,145,65,20,0,button,"Build");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(build);
define(100,210,10,65,20,3,button,"Exit");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(exit_prog);
define(110,140,10,65,20,3,button,"Info");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(info);
define(120,140,170,65,20,0,button,"GInsert");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(ginsert);
define(130,210,170,65,20,0,button,"GDelete");property(&b1,vga_font,NULL,BUTTONCOLOR);on_change(gdelete);
p=samples_total!=0;
set_enable(0,30,p);set_enable(0,40,p);set_enable(0,50,p);
redraw_window();
}
void main(int argc,char **argv)
{
if (argc!=2)
{
puts("MGF SoundTrack Editor ... (C) 1998 Ond©ej Nov k\n");
puts("Usage: MGIFEDIT <film.mgf>");
exit(1);
}
initialization();
set_mgif(argv[1]);
prj_name=get_project_name(mgif_filename);
switch (load_project(prj_name))
{
case -1:msg_box(PRG_HEADER,'\x1',"Chyba form tu v projektu!","Zav©¡t",NULL);shutdown();exit(1);
case -2:msg_box(PRG_HEADER,'\x1',"Neo‡ek van˜ eof souboru!","Zav©¡t",NULL);shutdown();exit(1);
}
init_editor();
warn_size_mistmach();
init_desktop();
control_window();
escape();
shutdown();
}

40
VIDEO/MGIFEDIT.H Normal file
View file

@ -0,0 +1,40 @@
#define concat(c,s1,s2) \
c=alloca(strlen(s1)+strlen(s2)+1);\
strcpy(c,s1);\
strcat(c,s2)
extern word boldcz;
extern word ikones;
extern void *icones;
extern void *vga_font;
extern word sipka;
extern int win_preview;
void shutdown();
#define crash(msg) \
{\
shutdown();\
printf("Module: %s\nLine: %d\nMessage: %s\n",__FILE__,__LINE__,msg);\
abort();\
}\
#define WINCOLOR 0x631f
#define LABELCOLOR 0x0f
#define BUTTONCOLOR (28*1024+24*32+3)
#define PRG_HEADER "MGIF Sound editor v1."VERSION
void show_full_lfb12e(void *source,void *target,void *palette);
#pragma aux show_full_lfb12e parm[esi][edi][ebx] modify [eax ecx edx]
void show_delta_lfb12e(void *source,void *target,void *palette);
#pragma aux show_delta_lfb12e parm[esi][edi][ebx] modify [eax ecx edx]
void show_full_interl_lfb130(void *source,void *target,void *palette);
#pragma aux show_full_interl_lfb130 parm[esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_lfb130(void *source,void *target,void *palette);
#pragma aux show_delta_interl_lfb130 parm[esi][edi][ebx] modify [eax ecx edx]
char test_next_frame(void *bufpos,int size);
#pragma aux test_next_frame parm [edi][ecx] modify [ebx] value [al]
void *sound_decompress(void *source,void *bufpos,int size,void *ampl_tab);
#pragma aux sound_decompress parm [esi][edi][ecx][ebx] modify [eax edx] value [edi]

275
VIDEO/MGIFEOBJ.C Normal file
View file

@ -0,0 +1,275 @@
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <malloc.h>
#include <memman.h>
#include <event.h>
#include <bmouse.h>
#include <gui.h>
#include <basicobj.h>
#include <zvuk.h>
#include <bgraph.h>
#include "mgifeobj.h"
#include "mgifedit.h"
#include "mgifeact.h"
static void done_bar_init(OBJREC *o,long *params)
{
o->userptr=New(long);
*(long *)o->userptr=*params;
}
static void done_bar_draw(int x1,int y1,int x2,int y2,OBJREC *o)
{
long value,max,x3;
value=*(long *)o->data;
max=*(long *)o->userptr;
x3=x1+(x2-x1)*value/max;
if (x3<=x1) x3=x1;
if (x3>=x2) x3=x2;
bar(x3,y1,x2,y2);
curcolor=o->f_color[1];
bar(x1,y1,x3,y2);
}
void done_bar(OBJREC *o) //define(...done_bar,max);
{
o->runs[0]=done_bar_init;
o->runs[1]=done_bar_draw;
o->datasize=4;
}
static void pic_view_draw(int x1,int y1,int x2,int y2,OBJREC *o)
{
void *pic;
x2,y2;
pic=*(void **)o->data;
if (pic!=NULL)
put_picture(x1,y1,pic);
}
void pic_viewer(OBJREC *o) //define(...pic_view);set_value(ptr)
{
o->runs[1]=pic_view_draw;
o->datasize=4;
}
//----------------------------------------
#define FRAME_SIZE 2
static void track_view_init(OBJREC *o,void **params)
{
o->userptr=New(void *);
memcpy(o->userptr,params,sizeof(void *));
}
static void track_view_draw(int x1,int y1,int x2,int y2,OBJREC *o)
{
int start;
int fstart;
int pos;
int midl=x1+x2>>1;
TRACK_DATA_T z,u,*p;
pos=*(int *)o->data;
start=(midl-pos*FRAME_SIZE);
if (start<x1)
{
fstart=(x1-start)/FRAME_SIZE;
start=x1;
}
else
{
fstart=0;
bar(x1,y1,start,y2);
}
curcolor=0x7fff;
bar(start,y1,x2,y2);
curcolor=0x7fe0;
bar(midl,y1,midl+1,y2);
p=&z;
get_vpoint(**(TRACK_DATA_T ***)o->userptr,fstart,&z);
curcolor=0;
while(p!=NULL && start+p->time*FRAME_SIZE<=x2)
{
int ys1,ys2;
ys1=y2-(y2-y1)*p->vpoint1/256;
ys2=y2-(y2-y1)*p->vpoint2/256;
curcolor=0;
bar(start-1,ys1-1,start+1,ys1+1);
curcolor=p->vpoint1==p->vpoint2?0:0x7c00;
line(start,ys1,start+p->time*FRAME_SIZE,ys2);
start+=p->time*FRAME_SIZE;
fstart+=p->time;
p=p->next;
}
if (p!=NULL)
{
int ys1,ys2;
get_vpoint(**(TRACK_DATA_T ***)o->userptr,fstart+(x2-start)/FRAME_SIZE,&u);
ys1=y2-(y2-y1)*p->vpoint1/256;
ys2=y2-(y2-y1)*u.vpoint1/256;
curcolor=0;
bar(start-1,ys1-1,start+1,ys1+1);
curcolor=p->vpoint1==p->vpoint2?0:0x7c00;
line(start,ys1,x2,ys2);
}
}
static int find_near_vpoint(TRACK_DATA_T *t,int frame,int yy,int nrf,int nrs)
{
int fr=0;
int nfr=frame,rz=nrf;
int p,q;
while (t!=NULL)
{
p=abs(fr-frame);
q=abs(t->vpoint1-yy);
if (p<rz && q<nrs)
{
nfr=fr;
rz=p;
}
fr+=t->time;
t=t->next;
}
return nfr;
}
static void track_view_click(EVENT_MSG *msg,OBJREC *o)
{
MS_EVENT *ms;
static int last_fr=-1;
if (msg->msg==E_MOUSE)
{
int x,y,*data;
int frel;
int frst;
int fr,nr;
int yy;
data=(int *)o->data;
ms=get_mouse(msg);
x=ms->x-o->locx;
y=ms->y-o->locy;
frel=x/2;
frst=o->xs/4-*data;
fr=frel-frst;
if (fr<0) fr=0;
if (fr>=total_frames) fr=total_frames-1;
yy=255-(y*256/o->ys);
if (yy<0) yy=0;
nr=find_near_vpoint(**(TRACK_DATA_T ***)o->userptr,fr,yy,5,10*256/o->ys);
if (ms->event_type & 0x8 && !ms->tl1)
{
*data=nr;
redraw_object(o);
set_change();
}
if (ms->event_type & 0x2) last_fr=nr;
else
if (ms->event_type & 0x4) last_fr=-1;
else
if (ms->tl1 && last_fr!=-1)
if (ms->event_type & 0x8)
{
delete_vpoint(*(TRACK_DATA_T ***)o->userptr,last_fr);
redraw_object(o);
last_fr=-1;
}
else
{
set_vpoint(*(TRACK_DATA_T ***)o->userptr,last_fr,yy,yy);
redraw_object(o);
}
}
if (msg->msg==E_LOST_FOCUS) last_fr=-1;
}
void track_view(OBJREC *o) //track_view(void *track);set_value(pos);
{
o->runs[0]=track_view_init;
o->runs[1]=track_view_draw;
o->runs[2]=track_view_click;
o->datasize=4;
}
#define FRAME_SIZE 2
static void starts_view_init(OBJREC *o,void **params)
{
o->userptr=New(void *);
memcpy(o->userptr,params,sizeof(void *));
}
static void starts_view_draw(int x1,int y1,int x2,int y2,OBJREC *o)
{
int start;
int fstart;
int pos;
int midl=x1+x2>>1;
int count;
TRACK_INFO_T *d;
int *list;
int i;
d=*(TRACK_INFO_T **)o->userptr;
list=d->starts;count=d->starts_count;
pos=*(int *)o->data;
start=(midl-pos*FRAME_SIZE);
if (start<x1)
{
fstart=(x1-start)/FRAME_SIZE;
start=x1;
}
else
{
fstart=0;
bar(x1,y1,start,y2);
}
curcolor=0x7fff;
bar(start,y1,x2,y2);
curcolor=0x7fe0;
bar(midl,y1,midl+1,y2);
for(i=0;i<count;i++)
{
int y;
y=list[i]-fstart;
if (y>=0 && y<(x2-x1)/FRAME_SIZE)
{
y*=FRAME_SIZE;
y+=start;
curcolor=0;
bar(y,y1,y+1,y2);
}
}
}
void starts_view(OBJREC *o) //track_view(void *track);set_value(pos);
{
o->runs[0]=starts_view_init;
o->runs[1]=starts_view_draw;
o->datasize=4;
}
static void color_box_draw(int x1,int y1,int x2,int y2,OBJREC *o)
{
curcolor=*(int *)o->data;
bar(x1,y1,x2,y2);
}
void color_box(OBJREC *o)
{
o->runs[1]=color_box_draw;
o->datasize=4;
}

6
VIDEO/MGIFEOBJ.H Normal file
View file

@ -0,0 +1,6 @@
void done_bar();
void pic_viewer();
void track_view(); //track_view(void *track);set_value(pos);
void starts_view(); //track_view(TRACK_INFO_T *x);set_value(pos);
void color_box(OBJREC *o); //color_box();set_value(color)

331
VIDEO/MGIFPLAY.C Normal file
View file

@ -0,0 +1,331 @@
// MOTION GIF - LZW komprimovana animace v rozliseni 320x180 256 barev avsak
// upravena pro prehravani v HICOLOR pro konkretni rezim (32768 barev)
// Format
/*
[ FRAME ] <pocet_chunku 1b><delka frame 3b>
[CHUNK] <cislo_akce 1b><delka_chunku 3b> !pozor delka je 3 bajtova (tj 16MB)
0 - PRADNY CHUNK
1 - LZW FULL SCREEN
2 - MGIF DELTA
3 - HICOLOR PALETE
4 - SOUND TRACK
5 - TEXT TRACK
6 - MGIF COPY
7 - SOUND INIT
Popis Chunku:
PRAZDNY_CHUNK - muze obsahovat soukrome informace
LZW_FULL_SCREEN
- ihned za hlavickou nasleduje LZW komprimovany obrazek
v rozliseni 320x180 256 barev
MGIF_DELTA
- cely blok je LZW komprimovany. Po dekomprimace blok obsahuje
dva druhy informaci. Prvni DWORD je ofset od pocatku dat
ktery ukazuje na zacatek graficke informace. Po tomto
DWORDU jsou ulozeny data o umisteni grafickych bodu v obrazu
Prvni byte znaci, kolik je nutne preskocit slov. (tj *2 byte)
Dalsi byte znaci, kolik je nutne zapsat slov (tj *2 byte)
Po tomto bytu je nutne prenest presne tolik slov z
grafickeho bloku na obrazovku. Dvojice bajtu se opakuji
dokud ani jeden z nich nema nejvyssi 2 bity nastavene.
Pak tento byte znaci ze uz na radce nic vic neni. Dolni cast
byte (tj 6 bitu) pak udava pocet radku, ktere je treba pre-
skocit. (nula=zadny).
HICOLOR PALETTE
- Prvni byte znamena pocet aktivnich barev. Pak nasleduje
paleta ve formatu xRRRRRGGGGGBBBBB. Rozdil oproti vsem
beznym paletam je v tom ze neni treba v palete udrzovat
barvy, ktere uz na obrazovce jsou, protoze zmena palety
se neprojevi na jiz zobrazenem obrazku.
SOUND_TRACK
- Kazdy frame obsahuje zvukovou stopu. Je to RAW format.
Pro verzi MGIF97 zde je zvukova informace ulozena ve
zvukove kvalite 16-bit stereo 22000Khz, ovsem komprimovana
na 50% jako MUS.
TEXT_TRACK
- Navic je ve mozne ve frame umistit textovou zpravu (titulek)
Prvni WORD udava dobu zobrazeni (pocet frame).
Pote nasleduje text zakoncen znakem 0;
MGIF_COPY - Za timto CHUNKEM je ulozen blok dat v nezakomprimovanem
tvaru(tj 57600byte);
*/
#include <stdio.h>
#include <stdlib.h>
#include <types.h>
#include <bgraph.h>
#include <memman.h>
#include <mem.h>
#include "lzw.h"
#include <zvuk.h>
#include <bios.h>
#include <vesa.h>
#include <i86.h>
#include <io.h>
//#include <sys\types.h>
//#include <sys\stat.h>
#include <fcntl.h>
#define MGIF "MGIF"
#define MGIF_Y "97"
#define VER 0x100
#define MGIF_EMPTY 0
#define MGIF_LZW 1
#define MGIF_DELTA 2
#define MGIF_PAL 3
#define MGIF_SOUND 4
#define MGIF_TEXT 5
#define MGIF_COPY 6
#define MGIF_SINIT 7
char konec=0;
void *bufpos;
long vals_save=0x80008000;
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
struct mgif_header gh;
int mgf;
int chunks;
word hipal[256];
char open_mgf_file(char *filename)
{
mgf=open(filename,O_BINARY | O_RDONLY);
if (mgf==-1) return 1;
read(mgf,&gh,sizeof(gh));
vals_save=0;
bufpos=NULL;
return 0;
}
void close_mgf_file()
{
close(mgf);
}
void load_frame(void *f)
{
long frame_head;
long frame_size;
read(mgf,&frame_head,4);
chunks=frame_head & 0xff;
frame_size=frame_head>>8;
read(mgf,f,frame_size);
}
void load_lzw_frame(void *p,void *temp)
{
reinit_lzw();
lzw_decode(p,temp);
}
void display_copy(char *temp)
{
char *c;
int i,j;
word *w,ww;
c=temp;
w=lbuffer+60*640;
for(i=0;i<180;i++)
{
for(j=0;j<320;j++)
{
ww=hipal[*c];
// w[640]=ww;
*w++=ww;
// w[640]=ww;
*w++=ww;
c++;
}
w+=640;
}
//showview(0,0,640,360);
}
void display_delta(char *temp)
{
char *graph,*contr,sk;
int i,j,k;
word *w,ww;
contr=temp;
graph=contr+*(long *)contr;
contr+=4;graph+=4;
for(i=0;i<180;i++)
{
w=lbuffer+1280*(i+30);sk=1;
while ((*contr & 0xc0)!=0xc0)
if (sk)
{
w+=(*contr++)*4;sk=!sk;
}
else
{
k=*contr++*2;
for(j=0;j<k;j++)
{
ww=hipal[*graph];
// w[640]=ww;
*w++=ww;
// w[640]=ww;
*w++=ww;
graph++;
}
sk=!sk;
}
i+=*contr++ & 0x3f;
}
// showview(0,0,640,360);
}
void show_full_interl_lfb(void *source,void *target,void *palette);
#pragma aux show_full_interl_lfb parm [esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_lfb(void *source,void *target,void *palette);
#pragma aux show_delta_interl_lfb parm [esi][edi][ebx] modify [eax ecx edx]
void show_full_interl_bank(void *source,void *target,void *palette);
#pragma aux show_full_interl_bank parm [esi][edi][ebx] modify [eax ecx edx]
void show_delta_interl_bank(void *source,void *target,void *palette);
#pragma aux show_delta_interl_bank parm [esi][edi][ebx] modify [eax ecx edx]
void *sound_decompress(void *source,void *bufpos,int size,void *ampl_tab);
#pragma aux sound_decompress parm [esi][edi][ecx][ebx] modify [eax edx] value [edi]
char test_next_frame(void *bufpos,int size);
#pragma aux test_next_frame parm [edi][ecx] modify [ebx] value [al]
void show_frame(void *fr,void *temp)
{
int x;
char *p,a;
long siz;
int frmode=0;
void *sound=NULL;int ssize;
p=fr;
for(x=0;x<chunks;x++)
{
a=*p;siz=*(long *)p>>8;p+=4;
switch(a)
{
case MGIF_LZW:
case MGIF_DELTA:load_lzw_frame(p,temp);frmode=a;break;
case MGIF_PAL:memcpy(hipal,p,siz);break;
case MGIF_COPY:temp=p;frmode=a;break;
case MGIF_SOUND:sound=p;ssize=siz;break;
}
p+=siz;
}
if (sound!=NULL)
{
while (test_next_frame(bufpos,ssize));
bufpos=sound_decompress(sound,bufpos,ssize,&gh.ampl_table);
}
else delay(50);
if (banking)
switch (frmode)
{
case MGIF_LZW:
case MGIF_COPY:show_full_interl_bank(temp,(word *)(60*2048),hipal);break;
case MGIF_DELTA:show_delta_interl_bank(temp,(word *)(60*2048),hipal);break;
}
else
switch (frmode)
{
case MGIF_LZW:
case MGIF_COPY:show_full_interl_lfb(temp,lbuffer+60*640,hipal);break;
case MGIF_DELTA:show_delta_interl_lfb(temp,lbuffer+(60)*640,hipal);break;
}
}
extern int test_counter;
void play_frames()
{
int x;
void *f,*temp;
f=getmem(65536);
temp=getmem(65536);
for(x=0;x<gh.frames;x++)
{
load_frame(f);
show_frame(f,temp);
if (_bios_keybrd(_KEYBRD_READY))
{
konec=1;
break;
}
}
test_counter-=gh.frames+40;
free(f);
free(temp);
}
main(int argc,char *argv[])
{
int a,b,c,d;
if (argc==1)
{
puts("Pouziti:");
puts("MGIFPLAY filename.mgf [snd_device] [port] [dma] [irq]");
exit(0);
}
initmode32();
if (argc>2)
{
sscanf(argv[2],"%d",&a);
sscanf(argv[3],"%x",&b);
sscanf(argv[4],"%d",&c);
sscanf(argv[5],"%d",&d);
}
else sound_detect(&a,&b,&c,&d);
set_mixing_device(a,22050,b,c,d);
start_mixing();delay(10);
init_lzw_compressor(8);
curcolor=0x0;
bar(0,0,639,479);showview(0,0,0,0);
do
if (open_mgf_file(argv[1])) konec=1;
else
{
play_frames();
close_mgf_file();
}
while (!konec);
done_lzw_compressor();
stop_mixing();
closemode();
}

209
VIDEO/OLD/MGIFMEM.C Normal file
View file

@ -0,0 +1,209 @@
#include <stdio.h>
#include <memman.h>
#include <mem.h>
#define MGIF "MGIF"
#define LZW_MAX_CODES 4096
#define LZW_BUFFER 64000
MGIF_PROC show_proc;
int mgif_frames;int cur_frame;
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
typedef struct double_s
{
short group,chr,first,next;
}DOUBLE_S;
typedef DOUBLE_S CODE_TABLE[LZW_MAX_CODES];
DOUBLE_S *compress_dic=NULL;
void *lzw_buffer=NULL;
int clear_code;
int end_code;
int free_code;
int nextgroup;
int bitsize,init_bitsize;
char old_value=0;
void do_clear_code()
{
int i;
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
for(i=0;i<clear_code;i++)
{
DOUBLE_S *p;
p=&compress_dic[i];
p->group=i;p->chr=-1;p->next=-1;p->first=-1;
}
}
void reinit_lzw()
{
do_clear_code();
}
void init_lzw_compressor(int dic_size)
{
if (compress_dic!=NULL)compress_dic=(CODE_TABLE *)getmem(sizeof(CODE_TABLE));
clear_code=1<<dic_size;
end_code=clear_code+1;
free_code=end_code+1;
nextgroup=free_code;
init_bitsize=bitsize=dic_size+1;
do_clear_code();
}
void done_lzw_compressor()
{
free(compress_dic);
compress_dic=NULL;
}
void mgif_install_proc(MGIF_PROC proc)
{
show_proc=proc;
}
void *open_mgif(void *mgif) //vraci ukazatel na prvni frame
{
char *c;
struct mgif_header *mgh;
c=mgif;
if (strncmp(c,MGIF)) return NULL;
mgh=mgif;
mgif_frames=mgh->frames;
cur_frame=0;
c+=sizeof(*mgh);
init_lzw_compressor(8);
if (lzw_buffer==NULL) lzw_buffer=getmem(LZW_BUFFER);
return c;
}
void close_mgif() //dealokuje buffery pro prehravani
{
done_lzw_compressor();
free(lzw_buffer);
lzw_buffer=NULL;
}
int input_code(void *source,long *bitepos,int bitsize,int mask);
#pragma aux input_code parm [esi][edi][ebx][edx]=\
"mov ecx,[edi]"\
"mov eax,ecx"\
"shr eax,3"\
"mov eax,[esi+eax]"\
"and cl,7"\
"shr eax,cl"\
"and eax,edx"\
"add [edi],ebx"\
value[eax] modify [ecx];
void de_add_code(DOUBLE_S *p,int *mask)
{
DOUBLE_S *q;
q=&compress_dic[nextgroup];q->group=p->group;q->chr=p->chr;q->first=compress_dic[p->group].first+1;
nextgroup++;
if (nextgroup==*mask)
{
*mask=(*mask<<1)+1;
bitsize++;
}
}
char fast_expand_code(int code,char **target);
#pragma aux fast_expand_code parm[eax][edi] modify [esi ecx] value [bl]
void lzw_decode(void *source,char *target)
{
long bitpos=0;
int code,old,i;
DOUBLE_S p;
int old_first;
int mask=0xff;
for(i=0;i<LZW_MAX_CODES;i++) compress_dic[i].first=0;
clear:
old_value=0;
nextgroup=free_code;
bitsize=init_bitsize;
mask=(1<<bitsize)-1;
code=input_code(source,&bitpos,bitsize,mask);
old_first=fast_expand_code(code,&target);
old=code;
while ((code=input_code(source,&bitpos,bitsize,mask))!=end_code)
{
if (code==clear_code)
{
goto clear;
}
else if (code<nextgroup)
{
old_first=fast_expand_code(code,&target);
p.group=old;
p.chr=old_first;
de_add_code(&p,&mask);
old=code;
}
else
{
p.group=old;
p.chr=old_first;
de_add_code(&p,&mask);
old_first=fast_expand_code(code,&target);
old=code;
}
}
}
void *mgif_play(void *mgif) //dekoduje a zobrazi frame
{
char *pf,*pc,*ff;
char acts,size,act,csize;
pf=mgif;
acts=*pf++;
size=*(int *)pf & 0xffffff;
pf+=3;pc=pf;pf+=size;
do
{
act=*pc++;csize=*(int *)pc & 0xffffff;pc+=3;
if (act==MGIF_LZW || act==MGIF_DELTA)
{
ff=lzw_buffer;
lzw_decode(pc,ff);
}
else
ff=pc;
show_proc(act,ff);
pc+=csize;
}
while (--acts);
return pf;
}

21
VIDEO/OLD/MGIFMEM.H Normal file
View file

@ -0,0 +1,21 @@
//!!!! POZOR, NUTNE LINKOVAT SOUBOR LZWA.ASM
typedef void (*MGIF_PROC)(int,void *); //prvni cislo akce, druhy data akce
#define MGIF "MGIF"
#define MGIF_Y "97"
#define VER 0x100
#define MGIF_EMPTY 0
#define MGIF_LZW 1
#define MGIF_DELTA 2
#define MGIF_PAL 3
#define MGIF_SOUND 4
#define MGIF_TEXT 5
#define MGIF_COPY 6
#define MGIF_SINIT 7
void mgif_install_proc(MGIF_PROC proc);
void *open_mgif(void *mgif); //vraci ukazatel na prvni frame
void *mgif_play(void *mgif); //dekoduje a zobrazi frame
void close_mgif(); //dealokuje buffery pro prehravani

892
VIDEO/PCX2MGIF.C Normal file
View file

@ -0,0 +1,892 @@
// MOTION GIF - LZW komprimovana animace v rozliseni 320x180 256 barev avsak
// upravena pro prehravani v HICOLOR pro konkretni rezim (32768 barev)
// Format
/*
[ FRAME ] <pocet_chunku 1b><delka frame 3b>
[CHUNK] <cislo_akce 1b><delka_chunku 3b> !pozor delka je 3 bajtova (tj 16MB)
0 - PRADNY CHUNK
1 - LZW FULL SCREEN
2 - MGIF DELTA
3 - HICOLOR PALETE
4 - SOUND TRACK
5 - TEXT TRACK
6 - MGIF COPY
7 - SOUND INIT
Popis Chunku:
PRAZDNY_CHUNK - muze obsahovat soukrome informace
LZW_FULL_SCREEN
- ihned za hlavickou nasleduje LZW komprimovany obrazek
v rozliseni 320x180 256 barev
MGIF_DELTA
- cely blok je LZW komprimovany. Po dekomprimace blok obsahuje
dva druhy informaci. Prvni DWORD je ofset od pocatku dat
ktery ukazuje na zacatek graficke informace. Po tomto
DWORDU jsou ulozeny data o umisteni grafickych bodu v obrazu
Prvni byte znaci, kolik je nutne preskocit slov. (tj *2 byte)
Dalsi byte znaci, kolik je nutne zapsat slov (tj *2 byte)
Po tomto bytu je nutne prenest presne tolik slov z
grafickeho bloku na obrazovku. Dvojice bajtu se opakuji
dokud ani jeden z nich nema nejvyssi 2 bity nastavene.
Pak tento byte znaci ze uz na radce nic vic neni. Dolni cast
byte (tj 6 bitu) pak udava pocet radku, ktere je treba pre-
skocit. (nula=zadny).
HICOLOR PALETTE
- Prvni byte znamena pocet aktivnich barev. Pak nasleduje
paleta ve formatu xRRRRRGGGGGBBBBB. Rozdil oproti vsem
beznym paletam je v tom ze neni treba v palete udrzovat
barvy, ktere uz na obrazovce jsou, protoze zmena palety
se neprojevi na jiz zobrazenem obrazku.
SOUND_TRACK
- Kazdy frame obsahuje zvukovou stopu. Je to RAW format.
Pro verzi MGIF97 zde je zvukova informace ulozena ve
zvukove kvalite 16-bit stereo 22000Khz, ovsem komprimovana
na 50% jako MUS.
TEXT_TRACK
- Navic je ve mozne ve frame umistit textovou zpravu (titulek)
Prvni WORD udava dobu zobrazeni (pocet frame).
Pote nasleduje text zakoncen znakem 0;
MGIF_COPY - Za timto CHUNKEM je ulozen blok dat v nezakomprimovanem
tvaru(tj 57600byte);
*/
#include <stdio.h>
#include <stdlib.h>
#include <types.h>
#include <bgraph.h>
#include <memman.h>
#include <mem.h>
#include <pcx.h>
#include "lzw.h"
#include <math.h>
#include <conio.h>
#include "jpegmgif.h"
#define MGIF "MGIF"
#define MGIF_Y "97"
#define VER 0x100
#define MGIF_EMPTY 0
#define MGIF_LZW 1
#define MGIF_DELTA 2
#define MGIF_PAL 3
#define MGIF_SOUND 4
#define MGIF_TEXT 5
#define MGIF_COPY 6
#define MGIF_SINIT 7
#define FRAME_X 320
#define FRAME_Y 180
#define FRAME_LEN (FRAME_X*FRAME_Y)
#define DELTA_LEN (3*FRAME_LEN)
#define LZW_LEN (2*FRAME_LEN)
#define SOUND_SPEED 44100
#define PRE_SOUND ((256*1024)/2)
#define ZTRATA lowq
#define BZTRATA colorq
#define MAX_FRAME max_fr
#define MIN_FRAME min_fr
#define BOXES_X 80
#define BOXES_Y 45
#define BOXES_ALL (BOXES_X*BOXES_Y)
#define SND_NAME ".SNF"
short mult_table[64];
short square_table[4096];
int statpic=0;
typedef struct mgif_header
{
char sign[4];
char year[2];
char eof;
word ver;
long frames;
word snd_chans;
int snd_freq;
short ampl_table[256];
short reserved[32];
};
word last_frame[FRAME_Y][FRAME_X];
char frame_delta[FRAME_LEN];
char delta_data[DELTA_LEN];
char frame_buffer[FRAME_LEN];
word color_state[32*32+32*32+32*32];
char calc_data[FRAME_LEN];
char flc_paleta[256][3];
int delta_data_size;
int frame_delta_size;
int speed=0;
int global_frame_counter=0;
int last_frame_size;
int total_frames;
int lowq=0;
int colorq=0;
int max_fr=99999;
int min_fr=0;
int hranice;
int hdiff=0;
int difdif=0;
TBOX *iib;
TBOX *rbb;
TBOX *gbb;
char *rgb_mem;
char frame_step=1;
struct mgif_header gh;
char lzw_buffer[LZW_LEN];
char pal_use[256],color_map[256];
word hipal[256],max_colors;
FILE *mgf;
long of_pos;
int of_chunks;
void open_frame()
{
of_chunks=0;
of_pos=ftell(mgf);
fwrite(&of_pos,1,4,mgf);
}
void close_frame()
{
long fsize,p;
last_frame_size=fsize=(p=ftell(mgf))-of_pos-4;
fseek(mgf,of_pos,SEEK_SET);
fwrite(&of_chunks,1,1,mgf);
fwrite(&fsize,1,3,mgf);
fseek(mgf,p,SEEK_SET);
total_frames++;
}
void write_chunk(char action,long size,void *data)
{
fwrite(&action,1,1,mgf);
fwrite(&size,1,3,mgf);
fwrite(data,1,size,mgf);
of_chunks++;
}
/*
void conv_2_hicolor()
{
int i,r,g,b;
for(i=0;i<256;i++)
{
r=(flc_paleta[i][0]>>3);
g=(flc_paleta[i][1]>>3);
b=(flc_paleta[i][2]>>3);
hipal[i]=((r<<10)+(g<<5)+b);
}
}
*/
void conv_2_rgb()
{
int i;
for(i=0;i<256;i++)
{
flc_paleta[i][0]=(hipal[i]>>10) & 0x1f;
flc_paleta[i][1]=(hipal[i]>>5)& 0x1f;
flc_paleta[i][2]=hipal[i]& 0x1f;
}
}
char find_color(word c); //najde barvu v palete a vraci byte
#pragma aux find_color parm [eax]=\
"mov edi,offset hipal"\
"mov ecx,256"\
"repne scasw"\
"mov eax,edi"\
"sub eax,offset hipal"\
"shr eax,1"\
"dec eax"\
value [al] modify[edi ecx];
void init_palmap()
{
int i;
memset(pal_use,0,sizeof(pal_use)); // nuluj pristupy k barvam
for(i=0;i<256;i++) color_map[i]=find_color(hipal[i]); //redukuj paletu;
max_colors=256; // pocet barev zatim 256;
}
int test_transp(char c,word w)
{
int r1,g1,b1;
int r2,g2,b2;
int diff;
r1=flc_paleta[c][0]>>3;
g1=flc_paleta[c][1]>>3;
b1=flc_paleta[c][2]>>3;
w&=0x7fff;
b2=w;g2=b2>>5;r2=g2>>5;b2&=0x1f;g2&=0x1f;
r1-=r2;g1-=g2;b1-=b2;
diff=r1*r1+g1*g1+b1*b1;
return diff<=hranice?diff:-1;
}
int change_color(char c1,char c2,int diff1)
{
int r1,g1,b1;
int r3,g3,b3;
int r4,g4,b4;
int diff2;
if (!diff1) return -1;
r1=flc_paleta[c1][0]>>3;
g1=flc_paleta[c1][1]>>3;
b1=flc_paleta[c1][2]>>3;
r3=flc_paleta[c2][0]>>3;
g3=flc_paleta[c2][1]>>3;
b3=flc_paleta[c2][2]>>3;
r4=r3-r1;g4=g3-g1;b4=b3-b1;
diff2=r4*r4+g4*g4+b4*b4;
if (diff2*2<diff1) return c2;else return -1;
}
void create_delta(char *frame_buffer)
{
char *delta;
char *data;
long colors2;
int x,y,i;
word *p;
char skip,skc,cpc;
char c1,c2,*a,d,c2old;
int d2;
delta=delta_data;
data=frame_delta;
a=frame_buffer;
c2old=color_map[*a];
for(y=0;y<180;y++)
{
p=&last_frame[y];
skip=1;
skc=0;
cpc=0;
for(x=0;x<160;x++)
{
c1=*a++;c2=*a++;
c1=color_map[c1];
c2=color_map[c2];i=0;
if ((d2=test_transp(c1,p[0]))>=0)
{/*if ((i=change_color(c1,c2old,d2))>=0) c1=i,d=0;else */d=1;}
else d=0;
c2old=c1;
if (d && (d2=test_transp(c2,p[1]))>=0)
{/*if (!d && (i=change_color(c2,c2old,d2))>=0) c2=i,d=0;else */d=1;}
else d=0;
c2old=c2;
if (d!=skip)
{
if (skip) *delta++=skc;else *delta++=cpc;
skip=!skip;skc=0;cpc=0;
}
if (!skip)
{
*data++=c1;
*data++=c2;
colors2=hipal[c1]+(hipal[c2]<<16);
*(long *)p=colors2;
cpc++;
}
else skc++;
p+=2;
pal_use[c1]=1;
pal_use[c2]=1;
}
if (!skip) *delta++=cpc;
if (skc==160 && *(delta-1)!=0xff && delta!=delta_data) delta[-1]++; //preskoc n radek
else *delta++=0xc0; //oznac konec radky
}
delta_data_size=delta-delta_data;
frame_delta_size=data-frame_delta;
}
void reduce_palette() //redukuje paletu na nejmensi nutny pocet barev
{
int i,j;
if (!speed) pal_use[0]=1;
for(i=0,j=0;i<256;i++)
{
if (pal_use[i])
{
hipal[j]=hipal[i];
color_map[i]=j++;
}
}
max_colors=j;
}
void filter_colors(void *block,int size,void *colormap); //prefiltruje blok dat podle color_map
#pragma aux filter_colors parm [edi][ecx][ebx]=\
"lp1: mov al,[edi]"\
" xlatb"\
" stosb"\
" loop lp1"\
modify [eax];
void *join_two_blocks(void *d1,void *d2,int siz1,int siz2,long *celk)
{
long siz;
char *d;
void *x;
siz=siz1+siz2+4;
d=(char *)getmem(siz);
x=d;
memcpy(d,&siz1,4);d+=4;
memcpy(d,d1,siz1);d+=siz1;
memcpy(d,d2,siz2);
*celk=siz;
return x;
}
void create_last_frame(void *source,void *target,void *pal,int size);
#pragma aux create_last_frame parm [esi][edi][ebx][ecx]=\
"lp1: lodsb"\
" movzx eax,al"\
" mov eax,[eax*2+ebx]"\
" stosw"\
" loop lp1"\
modify[eax]
void create_mgif_pal()
{
write_chunk(MGIF_PAL,max_colors*2,hipal);
}
void create_mgif_lzw()
{
int siz;
//conv_2_rgb();
init_palmap();
create_mgif_pal();
filter_colors(frame_buffer,FRAME_LEN,color_map);
create_last_frame(frame_buffer,last_frame,hipal,FRAME_LEN);
init_lzw_compressor(8);
memset(lzw_buffer,0,sizeof(lzw_buffer));
siz=lzw_encode(frame_buffer,lzw_buffer,FRAME_LEN);
if (siz>FRAME_LEN) write_chunk(MGIF_COPY,FRAME_LEN,frame_buffer);
else write_chunk(MGIF_LZW,siz,lzw_buffer);
done_lzw_compressor(8);
}
void create_color_state()
{
int i;
int r1,g1,b1;
int r2,g2,b2;
int diff;
char *c;
word *w;
memset(color_state,0,sizeof(color_state));
c=frame_buffer;
w=last_frame;
for(i=0;i<FRAME_LEN;i++)
{
r1=flc_paleta[*c][0]>>3;
g1=flc_paleta[*c][1]>>3;
b1=flc_paleta[*c][2]>>3;
b2=*w;g2=b2>>5;r2=g2>>5;b2&=0x1f;g2&=0x1f;
r1-=r2;g1-=g2;b1-=b2;
diff=abs(r1)+abs(g1<<1)+abs(b1);
color_state[diff]++;
c++;w++;
}
}
void set_max_color_change(int cchange)
{
int i,s;
s=0;cchange=57600-cchange;
for(i=sizeof(color_state)/sizeof(word)-1;s<cchange && i>0;i--) s+=color_state[i];
if (s>=cchange) i++;
hranice=i+hdiff;if (hranice<0) hranice=0;
}
int rozptyl(int v1,int v2)
{
int c1,c2,x,s;
x=v1+v2>>1;
c1=(x-v1);
c2=(x-v2);
s=c1*c1+c2*c2;
return s;
}
void create_low_quality()
{
void *snd;int l;
char *sn,*sr,c1,c2;
int rs,bs,gs;
l=FRAME_LEN;
sr=frame_buffer;
snd=calc_data;
sn=(char *)snd;
l--;
while (l--)
{
c1=*sr++;
c2=*sr;
rs=rozptyl(flc_paleta[c1][0],flc_paleta[c2][0]);
gs=rozptyl(flc_paleta[c1][1],flc_paleta[c2][1]);
bs=rozptyl(flc_paleta[c1][2],flc_paleta[c2][2]);
if (rs+gs+bs<ZTRATA)
{
*sn++=c1;
*sn++=c1;
sr++;if(!l--) break;
}
else
{
*sn++=c1;
*sn++=c2;
sr++;
if(!l--) break;
}
}
create_delta(snd);
}
void create_mgif_delta()
{
void *d;
long siz;
//conv_2_rgb();
init_palmap();
if (BZTRATA) create_color_state();
set_max_color_change(BZTRATA);
create_low_quality();
if (delta_data_size+frame_delta_size>FRAME_LEN)
{
create_mgif_lzw();
return;
}
if (!frame_delta_size) return;
reduce_palette();
filter_colors(frame_delta,frame_delta_size,color_map);
d=join_two_blocks(delta_data,frame_delta,delta_data_size,frame_delta_size,&siz);
init_lzw_compressor(8);
memset(lzw_buffer,0,sizeof(lzw_buffer));
siz=lzw_encode(d,lzw_buffer,siz);
done_lzw_compressor();
free(d);
if (siz>FRAME_LEN)
{
create_mgif_lzw();
return;
}
write_chunk(MGIF_DELTA,siz,lzw_buffer);
create_mgif_pal();
}
void prepare_for_mjpg()
{
iib=getmem(sizeof(TBOX)*BOXES_ALL);
rbb=getmem(sizeof(TBOX)*BOXES_ALL);
gbb=getmem(sizeof(TBOX)*BOXES_ALL);
memset(iib,0,sizeof(TBOX)*BOXES_ALL);
memset(rbb,0,sizeof(TBOX)*BOXES_ALL);
memset(gbb,0,sizeof(TBOX)*BOXES_ALL);
ibox=iib;
rbbox=rbb;
gbbox=gbb;
rgb_mem=getmem(FRAME_LEN*3);
create_cos_tab();
}
void create_jpg_frame()
{
int i,x,y,a;
char *dl=delta_data;
char *r=rgb_mem;
char *p=frame_buffer;
conv_2_rgb();
for(i=0;i<FRAME_LEN;i++)
{
*r++=flc_paleta[*p][0];
*r++=flc_paleta[*p][1];
*r++=flc_paleta[*p][2];
p++;
}
a=0;
for(y=0;y<BOXES_Y;y++)
for(x=0;x<BOXES_X;x++,a++)
{
int siz;
siz=transformace(rgb_mem+(y*4*12*BOXES_X+x*12),dl,320,a);
dl+=siz;
}
dl=delta_data;
a=0;
memset(iib,0,sizeof(TBOX)*BOXES_ALL);
memset(rbb,0,sizeof(TBOX)*BOXES_ALL);
memset(gbb,0,sizeof(TBOX)*BOXES_ALL);
for(y=0;y<BOXES_Y;y++)
for(x=0;x<BOXES_X;x++,a++)
{
zpetna_transformace(&dl,lbuffer+(y*8*BOXES_X+x)*8,a);
}
getchar();
}
void create_sound_track(int size)
{
void *p;
p=getmem(size);
memset(p,0,size);
write_chunk(MGIF_SOUND,size,p);
free(p);
}
void reserve_track()
{
int size;
if (!speed) return;
size=SOUND_SPEED/speed;
size&=~1;
create_sound_track(size);
}
void prereserve_tracks()
{
int size;
int celk;
if (!speed) return;
size=SOUND_SPEED/speed;
size&=~1;
celk=PRE_SOUND;
while (celk-size>0)
{
open_frame();
create_sound_track(size);
close_frame();
celk-=size;
}
if (celk)
{
open_frame();
create_sound_track(celk);
close_frame();
}
}
void fill_header(int frames)
{
memset(&gh,0,sizeof(gh));
strncpy(gh.sign,MGIF,4);
strncpy(gh.year,MGIF_Y,2);
gh.eof=26;
gh.ver=VER;
gh.frames=frames;
}
void show_screen()
{
word *c;
int i,j;
word *w;
c=last_frame;
w=screen;
for(i=0;i<180;i++)
{
for(j=0;j<320;j++)
{
*w++=*c;
*w++=*c;
c++;
}
w+=640;
}
showview(0,0,640,360);
showview(0,400,639,30);
}
void write_frame_size(int i,int col)
{
char s[200];
sprintf(s,"SIZE: %05d COLORS: %03d COMP.LEVEL %03d",i,col,hranice);position(0,400);outtext(s);
}
char *get_pcx_name(char *name,int x)
{
static char s[256];
char c[10],e[20],*z;
int d;
z=strchr(name,'#');
if (z==NULL)
{
memset(s,0,sizeof(s));
strncpy(s,name,240);
d=strlen(s);
if (x>9999)
{
s[d-1]=0;
sprintf(s,"%s%05d.pcx",s,x);
}
else sprintf(s,"%s%04d.pcx",s,x);
strupr(s);
}
else
{
int pocet,i;
pocet=0;
while(*z) if (*z++=='#') pocet++;
sprintf(c,"%%0%dd",pocet);
sprintf(e,c,x);
strcpy(s,name);
z=strchr(s,'#');
for(i=0;i<pocet;z++) if (*z=='#') *z=e[i],i++;
}
return s;
}
void write_frame_name(char *name,int x)
{
char s[256];
curcolor=0;bar(0,400,639,420);
sprintf(s,"FRAME: %d FILE: %s",x,get_pcx_name(name,x));position(0,410);outtext(s);
}
char get_pcx_frame(char *name,int x)
{
char *buf;
if (open_pcx(get_pcx_name(name,x),A_8BIT,&buf)) return 0;
memcpy(frame_buffer,buf+6+512,FRAME_LEN);
memcpy(hipal,buf+6,512);
free(buf);
return 1;
}
compress_pcx(char *name)
{
int x=0;
get_palette_ptr=flc_paleta;
curcolor=0;bar(0,0,639,479);
//prepare_for_mjpg();
while (get_pcx_frame(name,x))
{
open_frame();
if (x) create_mgif_delta();else create_mgif_lzw();
reserve_track();
//create_jpg_frame();
close_frame();
curcolor=0;bar(0,400,639,430);
write_frame_name(name,x);
write_frame_size(last_frame_size,max_colors);
if (last_frame_size>MAX_FRAME) {difdif=difdif<=0?1:difdif+1;hdiff+=difdif;}
else if (last_frame_size<MIN_FRAME && hranice>0) {difdif=difdif>=0?-1:difdif-1;hdiff+=difdif;}
else if (hdiff>0) {difdif=difdif>=0?-1:difdif-1;hdiff+=difdif;}else if(hdiff<0) hdiff=0;
show_screen ();
if (statpic) statpic--;else x+=frame_step;
global_frame_counter++;
}
}
void create_mgf_file(char *name)
{
mgf=fopen(name,"wb+");
fwrite(&gh,1,sizeof(gh),mgf);
total_frames=0;
prereserve_tracks();
}
void close_mgf_file()
{
fseek(mgf,0,SEEK_SET);
fill_header(total_frames);
fwrite(&gh,1,sizeof(gh),mgf);
fclose(mgf);
}
void create_mult_and_square()
{
int i;
puts("Creating tables...");
for(i=0;i<64;i++) mult_table[i]=(short)((i-32)*(i-32));
for(i=0;i<4096;i++) square_table[i]=(short)sqrt(i);
}
extern int boldcz;
void script_compress(char *script_name)
{
FILE *scr,*snf;
char s[256],name[256];
char snd_name[256],*c;
int i;
scr=fopen(script_name,"r");
strcpy(snd_name,script_name);
c=strrchr(snd_name,'.');
if (c==NULL) strcat(snd_name,SND_NAME);
else strcpy(c,SND_NAME);
if (scr==NULL)
{
printf("Nemohu otev©¡t script: %s\n",script_name);
exit(1);
}
snf=fopen(snd_name,"w");
i=fscanf(scr,"%255s",name);
if (i!=1)
{
printf("Chyba ve script souboru: %s. Prvni mus¡ b˜t jmno c¡lovho souboru.\n",scr);
exit(1);
}
i=fscanf(scr,"%d",&speed);
create_mgf_file(name);
while ((i=fgetc(scr))!=EOF && i!='\n');
i=fgetc(scr);
initmode32();
while (i!=EOF)
{
while (i<33 && i!=EOF) i=fgetc(scr);
if (i!='#')
{
int j=lowq;
ungetc(i,scr);
i=fscanf(scr,"%s %d %d %d %d",s,&j,&min_fr,&max_fr,&colorq);
strupr(s);
if (!strcmp(s,"FRAMESTEP")) frame_step=j;
else
if (!strcmp(s,"STATIC")) statpic=j;
else
if (i>=1)
{
lowq=j;
if (snf!=NULL) fprintf(snf,"%d ",global_frame_counter);
compress_pcx(s);
}
}
else
while ((i=fgetc(scr))!=EOF && i!='\n');
i=fgetc(scr);
}
closemode();
fclose(scr);
if (snf!=NULL) fclose(snf);
close_mgf_file();
}
main(int argc,char *argv[])
{
puts("\n(C)1997 Komprimator Motion GIF v0.9 by Ondrej Novak");
if (argc<2)
{
puts("Pouziti:");putchar('\n');;
puts("PCX2MGIF [d:\\path\\]source target.mgf [speed] [lowq] [min_fr] [max_fr] [colorq]");putchar('\n');
puts("source - Jsou 4 znaky kterymi zacina jmeno kazdeho frame (prvni 0). Takto je\n"
" mozne vytvorit animaci az o 9999 frames. Pokud je potreba delsi,pak\n"
" je ctvrty znak zmenen na cislo a je mozne vytvorit animaci dlouhou\n"
" az 99999 frames. Priklad:\n\n"
" PCX2MGIF logo logo.mgf \n\n"
" Tento zapis vytvori animaci logo.mgf, jenz bude slozena z mnoha\n"
" obrazku ve formatu PCX, jejichz jmena budou znit LOGO0000.PCX az\n"
" LOGO9999.PCX a dale bude pokracovat LOG10000.PCX az LOG99999.PCX\n\n"
"speed - Prehravaci rychlost ve snimkach za sekundu (pro 22050kHz)\n"
" Pokud je dosazeno 0 pak neni do animace vkladana zvukova stopa\n"
" (Default: 0)\n"
"lowq - Nejnizsi mozny rozptyl barev sousednich bodu (snizuje kvalitu\n"
" obrazu) (default: 0)\n"
"min_fr - Pozadavek na nejmensi velikost frame. Pod touto hranici v \n"
" nasledujicim frame snizi velikost ztraty (default: 0)");
cprintf("--- klavesu ---\r");getche();
puts("max_fr - Pozadavek na nejvetsi velikost frame. Pri prekroceni teto \n"
" hranice se zvysi ztrata o jeden bod. (default 99999)\n"
"colorq - Tato hodnota slouzi k predvidani velikosti ztraty. Udava\n"
" kolik bodu z celkoveho poctu zmen ve frame se menit nebude\n"
" Program pak vybere ty nejmensi rozdily a ty do rozdilove \n"
" mapy nezahrne. (default: 0)\n\n"
"Velikost nejmensiho rozdilu je zobrazen pri komprimaci jako treti cislo\n"
"Nula udava ze se nezapisuji jen ty body, ktere se nemeni.\n\n"
"Pozn1: Bezne neni nutne uvadet parametr colorq protoze stupen ztraty se \n"
"voli podle vysledku predchoziho frame. Je dobre ho uvest pri velkych\n"
"vykyvech velikosti frame. Tak zhruba pri ñ10KB. Hodnoty parametru se \n"
"voli od 25000-35000, cim vyssi, tim vyssi stupen ztraty\n\n"
"Pozn2: Pokud nektere parametry vynechas (treba znakem '-', nebo je na konci\n"
"neuvedes, dosadi se default hodnoty. Ty jsou zvoleny tak, aby program\n"
"nevypocitaval ztratu.\n");
exit(0);
}
curfont=(void *)&boldcz;
if (argc>2)
{
switch (argc)
{
case 8:sscanf(argv[7],"%d",&colorq);
case 7:sscanf(argv[6],"%d",&max_fr);
case 6:sscanf(argv[5],"%d",&min_fr);
case 5:sscanf(argv[4],"%d",&lowq);
case 4:sscanf(argv[3],"%d",&speed);
}
create_mgf_file(argv[2]);
initmode32();
compress_pcx(argv[1]);
closemode();
}
else
{
script_compress(argv[1]);
}
puts("Zaviram Motion GIF...");
close_mgf_file();
}

54
VIDEO/PLAY.C Normal file
View file

@ -0,0 +1,54 @@
#include <stdio.h>
#include <conio.h>
#include <graph.h>
#include <dos.h>
#include "flc.h"
#include "vesa.h"
void Set_TEXT_mode (void);
void main (int argc, char *argv[])
{
int x;
Open_FLC (argv[1]);
printf ("\nHlavicka FLC souboru %s:\n", argv[1]);
printf ("Delka celeho souboru: %d\n", h_flc.size);
printf ("Pocet frame: %d\n", h_flc.frames);
printf ("Velikost filmu: %dx%d\n", h_flc.width, h_flc.height);
printf ("Hloubka barvy: %d\n", h_flc.color);
// printf ("Rychlost prehravani: %d fps\n", 1000/h_flc.speed);
printf ("Offset prvniho frame: %d\n", h_flc.offset1);
getch ();
Set_VESA_mode (0x101);
delay (1000);
Get_first_frame ();
Decompress_frame ();
Show_screen (frame_buffer);
for (x=2; x<=h_flc.frames; x++)
{
Get_next_frame ();
Decompress_frame ();
Show_screen (frame_buffer);
delay (7);
}
getch ();
Set_TEXT_mode ();
Close_FLC ();
}
void Set_TEXT_mode (void)
{
union REGS inr, outr;
inr.h.ah = 0x00;
inr.h.al = 03;
int386 (0x10, &inr, &outr);
}

356
VIDEO/PLAYCNM.C Normal file
View file

@ -0,0 +1,356 @@
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bgraph.h>
#include <i86.h>
#include <bios.h>
#include "anipack.h"
#include "cinema.h"
#include <memman.h>
#define CINEMA ".cnm"
#define PLATNO_X 640
#define PLATNO_Y 184
#define PLATNO_S (PLATNO_X*PLATNO_Y)
#define POZICE (60)
#define DECOMP_BUFF 150000
FILE *anim;
word *playscreen;
word *playscreen2;
word *paleta;
word *show_place;
char *decomp_buff;
char *ip;
word direct_line_len=640*8;
char direct=0;
char fusing=1;
char ifuse=0;
char interlaced=0;
char sdiff=0;
char test_frame[120000];
void priponu(char *source,char *target,int n)
{
char *c,*d;
c=strrchr(source,'.');
d=strrchr(source,'\\');
strncpy(target,source,n);
if (c==NULL || c<d) strcat(target,CINEMA);
}
char col_table[]={0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
void decompr_box(word *adr)
{
char mode;
word palxlat[16];
int i;
mode=*ip++;
if (mode==0)
{
if ((*ip)--)
{
ip--;
return;
}
*ip=0;
mode=1;
}
if (mode==255)
{
ip--;
return;
}
if ((mode>16 && mode<64) || mode>64) exit(0);
if (mode<64)
{
for(i=0;i<mode;i++) palxlat[i]=paleta[*ip++];
mode=col_table[mode-1];
}
else mode=8;
switch (mode)
{
case 0:load_0bit(adr,palxlat);break;
case 1:ip=load_1bit(ip,adr,palxlat);break;
case 2:ip=load_2bit(ip,adr,palxlat);break;
case 3:ip=load_3bit(ip,adr,palxlat);break;
case 4:ip=load_4bit(ip,adr,palxlat);break;
case 8:ip=load_8bit(ip,adr,paleta);break;
}
}
void decompr_pict()
{
int x;
int y,yy;
ip=decomp_buff;
yy=0;
for (y=0;y<23;y++,yy+=direct_line_len)
for (x=0;x<640;x+=8)
decompr_box(playscreen+x+yy);
}
void load_frame(FILE *anim)
{
int size;
fread(&size,1,sizeof(size),anim);
fread(decomp_buff,1,size,anim);
decomp_buff[size]=0xff;
memcpy(test_frame,decomp_buff,size);
}
void load_palette(FILE *anim)
{
word i;
word size;
fread(&i,1,2,anim);
fread(&size,1,2,anim);
fread(&paleta[i],2,size,anim);
//if (fusing) for(i=1;i<256;i++) paleta[i]&=0x7bdf;
if (sdiff) paleta[0]=0;
}
void init_cinema()
{
playscreen=getmem(PLATNO_S*sizeof(*playscreen));
memset(playscreen,0xff,PLATNO_S*sizeof(*playscreen));
playscreen2=getmem(PLATNO_S*sizeof(*playscreen));
memset(playscreen2,0xff,PLATNO_S*sizeof(*playscreen));
paleta=getmem(512);
memset(paleta,0xff,sizeof(paleta));
if (banking) show_place=(word *)(POZICE*2048);else show_place=lbuffer+POZICE*640;
curcolor=0;bar(0,0,639,479);
showview(0,0,0,0);
decomp_buff=getmem(DECOMP_BUFF);
}
void done_cinema()
{
free(playscreen);
free(playscreen2);
free(paleta);
free(decomp_buff);
}
void fuse_frames()
{
long *p=(long *)playscreen,*q=(long *)playscreen2;
int i=PLATNO_S/2;
do
{
*q=(*q & 0x7bde7bde)+(*p & 0x7bde7bde)>>1;
q++;p++;i--;
}
while (i);
}
void copy_frames()
{
memcpy(playscreen2,playscreen,PLATNO_S*2);
}
void display_interlaced(word *playscreen2,int ofs)
{
word *p,*q;
int i=180;
p=show_place+ofs;
q=playscreen2;
do
{
if (banking) memcpy(mapvesaadr1(p),q,1280);else memcpy(p,q,1280);
q+=640;
p+=banking?2048:1280;i--;
}
while (i);
}
void display_full_lfb(word *playscreen2)
{
word *p,*q;
int i=180;
p=show_place;
q=playscreen2;
do
{
int j=320;
memcpy(p,q,1280);
p+=640;
do
{
*(long *)p=(*(long *)q & 0x7bde7bde)+(*(long *)(q+640) & 0x7bde7bde)>>1;q+=2;p+=2;j--;
}
while(j);
i--;
}
while (i);
}
void display_full_bank(word *playscreen2)
{
word *p,*q;
long *z;
int i=180;
p=show_place;
q=playscreen2;
do
{
int j=320;
memcpy(mapvesaadr1(p),q,1280);
p+=1024;
z=(long *)mapvesaadr1(p);
do
{
*z=(*(long *)q & 0x7bde7bde)+(*(long *)(q+640) & 0x7bde7bde)>>1;q+=2;z++;j--;
}
while(j);
p+=1024;
i--;
}
while (i);
}
void show_play_screen()
{
if (interlaced)
{
if (fusing)
{
if (ifuse) display_interlaced(playscreen,(banking?1024:640));
else
{
if (!banking) display_interlaced_fused_lfb(playscreen,playscreen2,show_place);
else display_interlaced_fused_bank(playscreen,playscreen2,show_place);
}
delay(30);
}
display_interlaced(playscreen,0);
}
else
{
if (fusing)
{
fuse_frames();
if (banking) display_full_bank(playscreen2);else display_full_lfb(playscreen2);
delay(30);
copy_frames();
}
if (banking) display_full_bank(playscreen);else display_full_lfb(playscreen);
}
}
void set_direct_mode()
{
fusing=0;
if (!banking)
{
direct=1;
playscreen=show_place;
anim_line_len=1280*2;
direct_line_len=640*16;
}
}
void play_cinema(FILE *anim)
{
char i;
do
{
fread(&i,1,1,anim);
switch (i)
{
case TRACK_VIDEO:
load_frame(anim);
decompr_pict();
break;
case TRACK_PALETTE:
load_palette(anim);
break;
case TRACK_MUSIC:break;
case TRACK_END:return;
case TRACK_DELAY:
if (!direct)
show_play_screen();
break;
default: return;
}
if (_bios_keybrd(_KEYBRD_READY)) return;
}
while (1);
}
void analyze_params(char *c)
{
while (*c)
switch (*c++)
{
case 'i':
case 'I':interlaced=1;break;
case 's':
case 'S':fusing=0;break;
case 'd':
case 'D':direct=1;break;
case 'v':
case 'V':sdiff=1;break;
case 'f':
case 'F':ifuse=1;interlaced=1;fusing=1;break;
}
}
void main(int argc,char **argv)
{
char filename[129];
if (argc<2)
{
puts("Pouziti: PLAYCNM film[.cnm] [I][D][S]");
puts(" I - Interlaced, prokladane");
puts(" S -Skip,vypina dvojnasobny pocet Framu");
puts(" D - Direct, prima dekomprese do LFB (totez jako IS, ale rychle)");
puts(" V - View differences, zobrazuje pouze rozdily (jen ty dulezite)");
puts(" F - Zapina specialni prokladaci rezim + I, ignoruje pri D");
return;
}
if (argc>=3) analyze_params(argv[2]);
priponu(argv[1],filename,124);
anim=fopen(filename,"rb");
if (anim==NULL)
{
printf("Nemohu otevrit soubor %s.\n",filename);
return;
}
if (initmode32(NULL))
{
puts("Tento program vyzaduje grafickou kartu, ktera podporuje HICOLOR 32768 barev") ;
return;
}
delay(1000);
init_cinema();
if (direct) set_direct_mode();
do
{
play_cinema(anim);
fseek(anim,0,SEEK_SET);
}
while (!_bios_keybrd(_KEYBRD_READY));
done_cinema();
closemode();
fclose(anim);
}

BIN
VIDEO/SADA7.FON Normal file

Binary file not shown.

102
VIDEO/VIDEO.C Normal file
View file

@ -0,0 +1,102 @@
#include <types.h>
#include <stdio.h>
#include <pcx.h>
#include <bgraph.h>
#include <memman.h>
#include <mem.h>
#include "bitline.h"
int komprimuj_rovinu(void *vstup, int velikost,int rovina,void *buffer,int *vysledek)
{
int i;
int m[4]={0,0,0,0},min,j;
char c[4][1930];
char *d;
buffer;vysledek;
rovina=1<<rovina;
for(i=0;i<4;i++)
{
switch (i)
{
case 0:d=(char *)cmode0(vstup,c[i],velikost,rovina);break;
case 1:d=(char *)cmode1(vstup,c[i],velikost,rovina);break;
case 2:d=(char *)cmode2(vstup,c[i],velikost,rovina);break;
case 3:d=(char *)cmode3(vstup,c[i],velikost,rovina);break;
}
m[i]=d-c[i];
}
if (m[0]<=m[1] && m[0]<=m[2]) j=0;
else if (m[0]>=m[1] && m[1]<=m[2]) j=1;
else j=2;
if (m[j]>=m[3]) j=3;
min=m[j];
printf("%5d %5d %5d %5d - %5d\n",m[0],m[1],m[2],m[3],min);
*vysledek=min;
memcpy(buffer,c[j],min);
return j;
}
void *decomprimuj_rovinu(void *vstup,void *vystup,int velikost,int rovina,int mode)
{
char *d;
mode>>=rovina*2;
mode&=0x3;
rovina=1<<rovina;
switch (mode)
{
case 0:d=cread0(vstup,vystup,velikost,rovina);break;
case 1:d=cread1(vstup,vystup,velikost,rovina);break;
case 2:d=cread2(vstup,vystup,velikost,rovina);break;
case 3:d=cread3(vstup,vystup,velikost,rovina);break;
}
return d;
}
void test()
{
char *pcx;
char *c;
void *d,*compr;
unsigned short *blckdata;
int vel,suma=0;
int i,j,m;
compr=getmem(640*480*3);d=compr;
open_pcx("d:\\!!!\\SKYNET\\TOMB\\DATA\\cred3.pcx",A_15BIT,&pcx);
c=pcx+2+2+2;
for (i=0;i<180*4;i++)
{
blckdata=d;blckdata[0]=i;blckdata[1]=0;blckdata[2]=0;
d=(char *)d+6;
for (j=0;j<15;j++)
{
m=komprimuj_rovinu(c,160,j,d,&vel);
blckdata[1+(j>>3)]|=m<<((j & 0x7)*2);
suma+=vel;
d=(char *)d+vel;
}
suma+=6;
c+=160*2;
}
printf("%d / %d / %d \n",180*20*15*4, suma, suma*100/(180*20*15*4));
c=pcx+2+2+2;
memset(c,0,640*480*2);
d=compr;
for (i=0;i<180*4;i++)
{
blckdata=d;
d=(char *)d+6;
for(j=0;j<15;j++)
d=decomprimuj_rovinu(d,&c[160*2*blckdata[0]],160,j,(int)blckdata[1]);
}
}
main()
{
test();
}