gates_of_skeldal/game/engine2.c
2025-01-31 18:54:59 +01:00

1317 lines
36 KiB
C

#include <platform/platform.h>
#include <libs/types.h>
#include "engine1.h"
#include <libs/bgraph.h>
#include <string.h>
typedef ZOOMINFO tzoom;
extern ZOOMINFO zoom;
extern word *screen;
void sikma_zleva(void)
{
int32_t scr_linelen2 = GetScreenPitch();
word *scr = (word *)zoom.startptr;
const word *palette = (word *)zoom.palette;
word cy = zoom.ycount;
const unsigned char *pixmap = zoom.texture;
const short *ytable = zoom.ytable;
while (cy) {
const int32_t *xtable = zoom.xtable;
word cx = zoom.xmax;
word *scr_iter = scr;
const unsigned char *pixmap_iter = pixmap;
while (cx > 0) {
unsigned char pb = *pixmap_iter++;
pixmap_iter+=*xtable;
xtable++;
if (pb == 1) break;
if (pb != 0) *scr_iter = palette[pb];
scr_iter++;
cx--;
}
pixmap+=zoom.texture_line*(*ytable);
ytable++;
scr-=scr_linelen2;
cy--;
}
/*
__asm
{
mov edi,zoom ;nacti ukazatel do obrazovky
mov ebx,[zoom]tzoom.palette ;ukazatel na paletu
mov cx,short ptr [zoom]tzoom.ycount ;velikost textury na y
shl ecx,16 ;vloz do horni pulky ecx
mov esi,[zoom]tzoom.texture ;nacti ukazatel na texturu
skzl3: mov edx,[zoom]tzoom.xtable ;nacti ukazetel na zvetsovaci tabulku x
push esi ;uchovej esi
push edi ;uchovej edi
mov cx,[zoom]tzoom.xmax
skzl1: xor eax,eax ;vynuluj eax pro spravny vypocet
lodsb ;nacti bod
add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x
add edx,4 ;posun se v tabulce x o dalsi polozku
or al,al ;test bodu na nulu
jz skz1 ;preskoc transparetni barvu
cmp al,1 ;test bodu na jedna
jz skz2 ;ukonci kresleni linky pokud narazi na 1
mov ax,[eax*2+ebx] ;konverze barvy podle palety
mov [edi],ax ;nakresli bod na obrazovce
skz1: add edi,2 ;dalsi pozice
dec cx
jnz skzl1 ;opakuj dokola
skz2: pop edi ;obnov edi
pop esi ;obnov esi
mov edx,[zoom]tzoom.ytable ;vyzvedni ukazatel na ytable
mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu
or cx,cx
jz skzskp
skzl2: add esi,[zoom]tzoom.texture_line ;posun o jednu pozici
dec cx ;sniz citac
jnz skzl2 ;dokud neni nula
skzskp:add edx,2 ;dalsi hodnota v tabulce
mov [zoom]tzoom.ytable,edx ;uloaz na puvodni misto
sub edi,[zoom]tzoom.line_len ;odecti tolik, kolik odpovida lince na obrazovce
sub ecx,10000h ;sniz horni pulku ecx o jedna
jnz skzl3 ;opakuj dokud neni nula
}*/
}
void sikma_zprava(void)
{
int32_t scr_linelen2 = GetScreenPitch();
word *scr = (word *)zoom.startptr;
const word *palette = (word *)zoom.palette;
word cy = zoom.ycount;
const unsigned char *pixmap = zoom.texture;
const short *ytable = zoom.ytable;
while (cy) {
const int32_t *xtable = zoom.xtable;
word cx = zoom.xmax;
word *scr_iter = scr;
const unsigned char *pixmap_iter = pixmap;
while (cx > 0) {
unsigned char pb = *pixmap_iter++;
pixmap_iter+=*xtable;
xtable++;
if (pb == 1) break;
if (pb != 0) *scr_iter = palette[pb];
scr_iter--;
cx--;
}
pixmap+=zoom.texture_line*(*ytable);
ytable++;
scr-=scr_linelen2;
cy--;
}
/*
__asm
{
mov edi,zoom ;nacti ukazatel do obrazovky
mov ebx,[zoom]tzoom.palette ;ukazatel na paletu
mov cx,short ptr [zoom]tzoom.ycount ;velikost textury na y
shl ecx,16 ;vloz do horni pulky ecx
mov esi,[zoom]tzoom.texture ;nacti ukazatel na texturu
skzp3: mov edx,[zoom]tzoom.xtable ;nacti ukazetel na zvetsovaci tabulku x
push esi ;uchovej esi
push edi ;uchovej edi
mov cx,[zoom]tzoom.xmax
skzp1: xor eax,eax ;vynuluj eax pro spravny vypocet
lodsb ;nacti bod
add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x
add edx,4 ;posun se v tabulce x o dalsi polozku
or al,al ;test bodu na nulu
jz skz3 ;preskoc transparetni barvu
cmp al,1 ;test bodu na jedna
jz skz4 ;ukonci kresleni linky pokud narazi na 1
mov ax,[eax*2+ebx] ;konverze barvy podle palety
mov [edi],ax ;nakresli bod na obrazovce
skz3: sub edi,2 ;dalsi pozice
dec cx
jnz skzp1 ;opakuj dokola
skz4: pop edi ;obnov edi
pop esi ;obnov esi
mov edx,[zoom]tzoom.ytable ;vyzvedni ukazatel na ytable
mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu
or cx,cx
jz skpskp
skzp2: add esi,[zoom]tzoom.texture_line ;posun o jednu pozici
dec cx ;sniz citac
jnz skzp2 ;dokud neni nula
skpskp: add edx,2 ;dalsi hodnota v tabulce
mov [zoom]tzoom.ytable,edx ;uloaz na puvodni misto
sub edi,[zoom]tzoom.line_len ;odecti tolik, kolik odpovida lince na obrazovce
sub ecx,10000h ;sniz horni pulku ecx o jedna
jnz skzp3 ;opakuj dokud neni nula
}*/
}
void fcdraw(const void *source,void *target, const void *table)
//#pragma aux fcdraw parm [EDX][EBX][EAX] modify [ECX ESI EDI];
{
word *src = (word *)source;
word *trg = (word *)target;
T_FLOOR_MAP *t = (T_FLOOR_MAP *)table;
uint32_t cc;
do {
word *ss = t->txtrofs/2+src;
word *tt = t->lineofs/2+trg;
cc = t->linesize;
memcpy(tt,ss,cc*2);
cc = t->counter;
t++;
} while (cc != 0);
/*
__asm
{
mov edx,source
mov ebx,target
mov eax,table
;Kresli strop nebo podlahu podle draw_table
;EDX - sourceTxt
;EBX - TargerTxt - LineOfset
; (Lineofs je pocet bajtu odpovidajici
; souradnicim [0,184] pro podlahu nebo [0,0]
; pro strop)
;EAX - draw_table
fcdraw_:mov esi,[eax+12]
mov edi,[eax]
add edi,ebx
add esi,edx
mov ecx,[eax+4]
shr ecx,1
rep movsd
rcl ecx,1
rep movsw
mov ecx,[eax+8]
add eax,16
or ecx,ecx
jnz fcdraw_
}*/
}
void klicovani_anm_back(void *target,void *source);
void klicovani_anm(void *target,void *source,char mirror)
//#pragma aux klicovani_anm parm [edi][esi][eax] modify [ecx edx ebx]
{
int32_t scr_linelen2 = GetScreenPitch();
word *t = (word *)target;
word *s = (word *)source;
if (mirror) {
unsigned int l = 180;
while (l > 0) {
unsigned int c = 640;
while (c > 0) {
word p = *s++;
if ((p & 0x8000 ) == 0) {
p = p + (p & ~0x1F);
--c;
t[c] = p;
t[c+scr_linelen2] = p;
--c;
t[c] = p;
t[c+scr_linelen2] = p;
} else {
c-=2;
}
}
t+=2*scr_linelen2;
--l;
}
} else {
unsigned int l = 180;
while (l > 0) {
unsigned int c = 320;
while (c > 0) {
word p = *s++;
if ((p & 0x8000 ) == 0) {
p = p + (p & ~0x1F);
t[0] = p;
t[scr_linelen2] = p;
++t;
t[0] = p;
t[scr_linelen2] = p;
++t;
} else {
t+=2;
}
--c;
}
t+=scr_linelen2;
--l;
}
}
}
/*
__asm
{
mov edi,target
mov esi,source
mov cl,180
ka_lp2: mov ebx,320
ka_lp1: lodsw
movzx eax,ax
test eax,0x8000
jnz ka_skip
mov edx,eax
and edx,0x7FE0
add eax,edx
mov edx,eax
shl edx,16
add edi,scr_linelen
or eax,edx
mov [edi],eax
sub edi,scr_linelen
mov [edi],eax
ka_skip:add edi,4
dec ebx
jnz ka_lp1
sub edi,1280
add edi,scr_linelen
add edi,scr_linelen
dec cl
jnz ka_lp2
}
}
static void klicovani_anm_back(void *target,void *source)
//#pragma aux klicovani_anm parm [edi][esi][eax] modify [ecx edx ebx]
{
__asm
{
mov edi,target
mov esi,source
mov ecx,180
add edi,1280
kba_lp2: mov ebx,320
kba_lp1: lodsw
sub edi,4
movzx eax,ax
test eax,0x8000
jnz kba_skip
mov edx,eax
and edx,0x7FE0
add eax,edx
mov edx,eax
shl edx,16
add edi,scr_linelen
or eax,edx
mov [edi],eax
sub edi,scr_linelen
mov [edi],eax
kba_skip:dec ebx
jnz kba_lp1
add edi,scr_linelen
add edi,scr_linelen
add edi,1280
dec ecx
jnz kba_lp2
}
}
*/
#define zobraz_1 \
__asm lodsb \
__asm movzx eax,al \
__asm movzx eax,short ptr [eax*2+ebx] \
__asm stosw \
void small_anm_buff(void *target,void *buff,void *paleta)
//#pragma aux small_anm_buff parm[edi][esi][ebx] modify [eax ecx]
{
int32_t scr_linelen2 = GetScreenPitch();
word *t = (word *)target;
unsigned char *s = (unsigned char *)buff;
word *p = (word *)paleta;
int i,j;
for ( i = 0; i < 180; i++) {
for (j = 0; j < 320; j++) {
*t++ = p[*s++];
}
t+=scr_linelen2-320;
}
/*
__asm
{
mov edi,target;
mov esi,buff;
mov ebx,paleta
mov ecx,179*10000h
shmab4: mov cx,320
shmab3: zobraz_1
dec cx
jnz shmab3
add edi,640
sub ecx,010000h
jnc shmab4
}*/
}
void small_anm_delta(void *target,void *buff,void *paleta)
//#pragma aux small_anm_delta parm[edi][esi][ebx] modify [eax ecx]
{
int32_t scr_linelen2 = GetScreenPitch();
word *t = (word *)target;
word *pal = (word *)paleta;
uint32_t *deltastart = (uint32_t *)buff;
uint32_t ofs = *deltastart++;
unsigned char *control = (unsigned char *)deltastart;
unsigned char *pixels = control + ofs;
int y;
for (y = 0; y < 180; y++) {
word *tp = t;
do {
unsigned char c = *control++;
if (c >= 0xc0) {
//skip line
unsigned char d = c - 0xc0;
y+=d;
t+=(d+1)*scr_linelen2;
break;
} else {
tp+=2*c;
c = *control++;
while (c) {
*tp++ = pal[*pixels++];
*tp++ = pal[*pixels++];
c--;
}
}
} while (1);
}
}
/*
__asm
{
mov edi,target;
mov esi,buff;
mov ebx,paleta
mov ch,180 ;180 radek
mov eax,[esi] ;vem offset na delta data
lea edx,[esi+eax+4] ;ebp obsahuje tento offset
lea esi,[esi+4] ;esi obsahuje offset na delta control
shmad5: push edi ;uchovej zacatek radky
shmad3: lodsb ;vem skip hodnotu
mov ah,al ;uchovej ji ah - kvuli destruktivnimu testu
and al,not 3fh ;na posledni 2 bity
cmp al,0c0h ;C0 a vyssi znamenaji ze se preskakuje radek
jz shmad1 ;pri pozitivnim testu je preskoc
movzx eax,ah ;vem skip hodnotu do eax
shl eax,2 ;na obrazovce *2 bodu *1 zoom *2 za bod (x4)
add edi,eax ;pricti k edi
lodsb ;vem copy hodnotu
mov cl,al ;zaved counter
xchg esi,edx ;prohod ukazatele control a data
shmad2: zobraz_1 ;zobraz bod
zobraz_1 ;zobraz bod
dec cl ;opakuj tolikrat kolik je copy hodnota
jnz shmad2
xchg esi,edx ;prohod ukazatele control a data
jmp shmad3 ;a precti dalsi skip hodnotu
shmad1: pop edi
and ah,03fh ;maskuj spodnich 6 bitu
inc ah ;+1
shmad4: add edi,scr_linelen
dec ch ;odecti counter radek
dec ah ;odecti counter
jnz shmad4 ;a opakuj ah krat
or ch,ch ;je li counter nulovy tak padame
jnz shmad5
}*/
void scroll_and_copy(const void *pic,void *slide, void *scr, int _size,int shift, void *lineinfo)
//#pragma aux scroll_and_copy parm[esi][ebx][edi][ecx][edx][eax]
{
int32_t scr_linelen2 = GetScreenPitch();
word *srcpc = (word *)pic;
word *trg = (word *)scr;
word *sld = (word *)slide;
int shiftofs = shift*scr_linelen2;
int lc = _size;
int *lnfo = (int *)lineinfo;
int y;
for (y = 0; y < lc; y++ ) {
int left = MIN(lnfo[0],lnfo[2]);
int right = MAX(lnfo[1],lnfo[3]);
int x;
for (x = left; x <= right; x++) {
word c = sld[x] = sld[x+shiftofs];
if (c & BGSWITCHBIT) {
trg[x] = srcpc[x];
} else {
trg[x] = c;
}
}
sld+=scr_linelen2;
trg+=scr_linelen2;
srcpc+=scr_linelen2;
lnfo+=2;
}
/*
__asm
{
mov esi,pic
mov ebx,slide
mov edi,scr
mov ecx,_size
mov edx,shift
mov eax,lineinfo
;odscroluje a kopiruje obrazovku do screenu
;pouzitelne pro titulky
;0x8000 je transparentni
;edi screen
;ebx buffer
;esi back_picture
;ecx velikost bufferu (pocet_radku)
;edx pocet bajtu o kolik je nutne posouvat (*1280)
;eax - ukazatel na tittle lines
push ebp
mov ebp,eax ;uloz ukazatel na titlelines
mov eax,edx
imul eax,scr_linelen
sac_lp1:push ecx
push eax
mov eax,[ebp] ;nacti zac
mov ecx,[ebp+edx*8]
cmp eax,ecx
jc sac_sk1
mov eax,ecx
sac_sk1:shl eax,1 ;adresa
add esi,eax ;pricti k pointrum
add edi,eax
add ebx,eax
add ebp,4 ;presun se na kon
shr eax,1 ;eax je zacatek v bodech
mov ecx,[ebp+edx*8] ;vem konec
cmp ecx,[ebp]
jnc sac_sk2
mov ecx,[ebp]
sac_sk2:push ecx
sub ecx,eax ;kon-zac+1=celk pocet
xchg edx,[esp+4]
sac_lp2:mov eax,[ebx+edx] ;Vem data na dalsim radku
mov [ebx],eax ;Zapis je sem
add ebx,4 ;dalsi pozice
test eax,~BGSWITCHBIT ;je to transparentni?
jz sac_all ;pokud ano, zobraz_obrazek
bt eax,5 ;test bitu 15
jnc sac_1 ;Neni nastaven - zobraz primo barvu
mov ax,[esi] ;jinak vem barvu z obrazku
sac_1: stosw ;zapis barvu
add esi,2 ;dalsi pozice
rol eax,16 ;presun eax na dolni slovo
bt eax,5 ;test bitu 15
jnc sac_2 ;neni nastaven - zobraz primo barvu
mov ax,[esi] ;jinak vem barvu z obrazku
sac_2: stosw ;zapis barvu
add esi,2 ;dalsi pozice
jmp sac_end
sac_all:movsd ;presun celeho slova
sac_end:sub ecx,2 ;odecti counter
ja sac_lp2 ;je li nad opakuj
add ecx,640 ;pricti sirku, - kolik jsme prejeli
pop eax
sub ecx,eax ;odecti konec -> kolik preskocit
add ebp,4 ;aktualizuj ukazatele
shl ecx,1 ;v adresach
add esi,ecx
push edx
mov edx,scr_linelen
sub edx,1280
add ecx,edx
add edi,ecx
add ebx,ecx
pop edx
pop eax
xchg edx,eax
pop ecx ;obnov ecx
dec ecx ;sniz citac radku
jnz sac_lp1 ;dokud neni nula
pop ebp ;obnov ebp
}
*/
}
#define pic_start 2+2+2+512*5+512*5
#define ed_stack 800*4+600*4
#define ed_stk1 600*4
void enemy_draw(const void *src,void *trg,int shade,int scale,int maxspace,int clip)
//#pragma aux enemy_draw parm[ESI][EDI][EBX][EDX][EAX][ECX]
{
int32_t scr_linelen2 = GetScreenPitch();
word *picinfo = (word *)src;
word *screen = (word *)trg;
int xtable[800];
int ytable[1200];
int xcount;
word pcx = picinfo[0];
word pcy = picinfo[1];
unsigned char *picdata = (unsigned char *)src + pic_start;
word *palette = picinfo+shade/2;
int clipl = clip & 0xFFFF;
int clipr = clip >> 16;
int yiter;
if (maxspace >= 470) return;
//prepare ytable;
{
int rwofs = pcx*(pcy-1);
int accu = 0;
int *w = ytable;
int sp = maxspace*2;
while (sp > 0 && rwofs >= 0) {
*w++ = rwofs;
accu+=320;
while (accu >= scale && rwofs >= 0) {
accu-=scale;
rwofs-=pcx;
}
sp--;
}
*w++=-1;
//ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1
}
//prepare xtable
{
int *w = xtable;
int ofs = 0;
int accu = 0;
while (ofs < pcx) {
*w++ = ofs;
accu+=320;
while (accu >= scale) {
accu-=scale;
ofs++;
}
}
xcount = w - xtable;
*w++=-1;
//xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1
}
if (clipl > xcount) return;
yiter = 0;
while (ytable[yiter] >= 0) {
int xiter = clipl;
int ofs = ytable[yiter];
unsigned char *row = picdata+ofs;
while (xiter < clipr && xtable[xiter] >= 0 ) {
int xpos = xiter;
unsigned char p = row[xtable[xiter]];
if (p != 0) {
if (p == 1) screen[xpos] = (screen[xpos] & 0xF7DE) >> 1;
else screen[xpos] = palette[p];
}
++xiter;
}
screen-=scr_linelen2;
++yiter;
}
/*
__asm
{
mov esi,src
mov edi,trg
mov ebx,shade
mov edx,scale
mov eax,maxspace
mov ecx,clip
cmp eax,470
jc ed_ok1
ret
ed_ok1: push ebp
sub esp,ed_stack ;vyhrad zasobnik
mov ebp,esp
push ecx ;uchovej ecx +1
push edi ;uchovej edi +2
push ebx ;uchovej ebx +3
mov ebx,eax ;volne misto je ted v ebx
mov edi,ebp ;nastav edi na zacatek tabulek
push ebp ; +4
movzx ecx,short ptr[esi] ;precti xs
movzx eax,short ptr[esi+2] ;precti ys
imul eax,ecx ;xs*ys
sub eax,ecx ;minus 1 radek
xor ebp,ebp
ed_lp1b:stosd ;zapis hodnotu do tabulky
add ebp,320 ;zmensovani
ed_lp1a:cmp ebp,edx
jc ed_nxt1 ;pri ebp<edx pokracuj dal
sub ebp,edx
sub eax,ecx ;odecti radku
jbe ed_end1 ;pokud je to posledni tak konec1
jmp ed_lp1a
ed_nxt1:dec ebx
jnz ed_lp1b
ed_end1:xor eax,eax
dec eax
stosd ;tabulka pro y je hotova
pop ebp ; +3
lea edi,[ebp+ed_stk1] ;nastav se na druhou tabulku
xor eax,eax ;vynuluj vypoctove registry
xor ebx,ebx
movzx ecx,short ptr[esi] ;ecx je velikost obrazku v x
ed_nxt2:stosd ;zapis x souradnici
add ebx,320 ;pocitej zmenseni
ed_lp2a:cmp ebx,edx
jc ed_nxt2
sub ebx,edx
inc eax
cmp eax,ecx ;pokud je x>=velikosti obrazku tak konec
jc ed_lp2a
xor eax,eax
dec eax ;zapis -1 na konec tabulky
pop ebx ; +2
stosd
mov eax,edi ;konecnou pozici pro tabulku x zapis do eax
pop edi ;obnov registry edi exc ebx+1
add ebx,esi ;najdi adresu prekladove tabulky barev
add ebx,2 ;preskoc transparentni barvu
add esi,pic_start;presun se na zacatek obrazku
pop ecx ; +0
movzx edx,cx ;vem levy okraj
lea edx,[ebp+edx*4]
lea edx,[edx+ed_stk1];edx ukazuje na sloupce
cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec
jbe ed_err
shr ecx,16 ;ecx ted obsahuje pravy okraj
ed_lp4: push esi ;uchovej esi +1
push edi ;uchovej edi +2
add esi,[ebp] ;spocitej spravnou hodnotu esi
push ecx ;uchovej pravy okraj +3
push edx ;uchovej ukazatel na tabulku+4
ed_lp3: mov eax,[edx]
cmp eax,-1 ;testuj konec tabulky
jz ed_end3 ;pri pozitivnim vysledku => konec radky
movzx eax,byte ptr[esi+eax];vem barvu
or al,al
jz ed_skp1 ;preskoc transparentni barvu
dec al
jz ed_shd ;1=shadow
mov eax,[ebx+eax*2];vyzvedni hicolor
stosw ;zapis barvu
jmp ed_skp2
ed_shd: movzx eax,short ptr[edi];vem barvu
and eax,0xF7DE ;stmav
shr eax,1
stosw ;zapis
jmp ed_skp2 ;skok na konec
ed_skp1:add edi,2 ;preskoc bod
ed_skp2:add edx,4 ;dalsi pozice
dec ecx ;dokud nedosahneme praveho okraje obrazku
jnz ed_lp3
ed_end3:pop edx ;obnov vse ulozene
pop ecx
pop edi
pop esi ; +0
add ebp,4 ;dalsi y souradnice
sub edi,scr_linelen ;dalsi radka
cmp dword ptr [ebp],-1 ;test na konec tabulky
jnz ed_lp4 ;jinak pokracuj
ed_err: add esp,ed_stack;vymaz tabulku
pop ebp ;obnov ebp
}
*/
}
void enemy_draw_transp(const void *src,void *trg,const void *shade,int scale,int maxspace,int clip)
//#pragma aux enemy_draw_transp parm[ESI][EDI][EBX][EDX][EAX][ECX]
{
int32_t scr_linelen2 = GetScreenPitch();
word *picinfo = (word *)src;
word *screen = (word *)trg;
int xtable[800];
int ytable[1200];
int xcount;
word pcx = picinfo[0];
word pcy = picinfo[1];
word type = picinfo[2];
unsigned char *picdata = (unsigned char *)src+(type == (512+8)?6:pic_start);
word *palette = (word *)shade;
int clipl = clip & 0xFFFF;
int clipr = clip >> 16;
int yiter;
if (maxspace >= 470) return;
//prepare ytable;
{
int rwofs = pcx*(pcy-1);
int accu = 0;
int *w = ytable;
int sp = maxspace*2;
while (sp > 0 && rwofs >= 0) {
*w++ = rwofs;
accu+=320;
while (accu >= scale && rwofs >= 0) {
accu-=scale;
rwofs-=pcx;
}
sp--;
}
*w++=-1;
//ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1
}
//prepare xtable
{
int *w = xtable;
int ofs = 0;
int accu = 0;
while (ofs < pcx) {
*w++ = ofs;
accu+=320;
while (accu >= scale) {
accu-=scale;
ofs++;
}
}
xcount = w - xtable;
*w++=-1;
//xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1
}
if (clipl > xcount) return;
yiter = 0;
while (ytable[yiter] >= 0) {
int xiter = clipl;
int ofs = ytable[yiter];
unsigned char *row = picdata+ofs;
while (xiter < clipr && xtable[xiter] >= 0 ) {
int xpos = xiter -clipl;
unsigned char p = row[xtable[xiter]];
if (p != 0) {
if (p & 0x80) screen[xpos] = ((screen[xpos] & 0xF7DE) + (palette[p] & 0xF7DE))>>1;
else screen[xpos] = palette[p];
}
++xiter;
}
screen-=scr_linelen2;
++yiter;
}
/* __asm
{
mov esi,src
mov edi,trg
mov ebx,shade
mov edx,scale
mov eax,maxspace
mov ecx,clip
cmp eax,470
jc et_ok1
ret
et_ok1: push ebp
sub esp,ed_stack ;vyhrad zasobnik
mov ebp,esp
push ecx ;uchovej ecx +1
push edi ;uchovej edi +2
push ebx ;uchovej ebx +3
mov ebx,eax ;volne misto je ted v ebx
mov edi,ebp ;nastav edi na zacatek tabulek
push ebp ; +4
movzx ecx,short ptr[esi] ;precti xs
movzx eax,short ptr[esi+2] ;precti ys
imul eax,ecx ;xs*ys
sub eax,ecx ;minus 1 radek
xor ebp,ebp
et_lp1b:stosd ;zapis hodnotu do tabulky
add ebp,320 ;zmensovani
et_lp1a:cmp ebp,edx
jc et_nxt1 ;pri ebp<edx pokracuj dal
sub ebp,edx
sub eax,ecx ;odecti radku
jbe et_end1 ;pokud je to posledni tak konec1
jmp et_lp1a
et_nxt1:dec ebx
jnz et_lp1b
et_end1:xor eax,eax
dec eax
stosd ;tabulka pro y je hotova
pop ebp ; +3
lea edi,[ebp+ed_stk1] ;nastav se na druhou tabulku
xor eax,eax ;vynuluj vypoctove registry
xor ebx,ebx
movzx ecx,short ptr[esi] ;ecx je velikost obrazku v x
et_nxt2:stosd ;zapis x souradnici
add ebx,320 ;pocitej zmenseni
et_lp2a:cmp ebx,edx
jc et_nxt2
sub ebx,edx
inc eax
cmp eax,ecx ;pokud je x>=velikosti obrazku tak konec
jc et_lp2a
xor eax,eax
dec eax ;zapis -1 na konec tabulky
pop ebx ; +2
stosd
mov eax,edi ;konecnou pozici pro tabulku x zapis do eax
pop edi ;obnov registry edi exc ebx+1
cmp byte ptr [esi+5],2 ;obrazek bez palety?
jz et_pl1
add esi,pic_start;presun se na zacatek obrazku (za paletu)
jmp et_pl2
et_pl1: add esi,6 ;(obrazek bez palety, presun se za hlavicku)
et_pl2: pop ecx ; +0
movzx edx,cx ;vem levy okraj
lea edx,[ebp+edx*4]
lea edx,[edx+ed_stk1];edx ukazuje na sloupce
cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec
jbe et_err
shr ecx,16 ;ecx ted obsahuje pravy okraj
et_lp4: push esi ;uchovej esi +1
push edi ;uchovej edi +2
add esi,[ebp] ;spocitej spravnou hodnotu esi
push ecx ;uchovej pravy okraj +3
push edx ;uchovej ukazatel na tabulku+4
et_lp3: mov eax,[edx]
cmp eax,-1 ;testuj konec tabulky
jz et_end3 ;pri pozitivnim vysledku => konec radky
movzx eax,byte ptr[esi+eax];vem barvu
test al,80h
jnz et_shd
or al,al
jz et_skp1 ;preskoc transparentni barvu
mov eax,[ebx+eax*2];vyzvedni hicolor
stosw ;zapis barvu
jmp et_skp2
et_shd: and short ptr[edi],0xF7DE ;1111 0111 1101 1110
mov eax,[ebx+eax*2];vyzvedni hicolor
and eax,0xF7DE ;stmav
add ax,short ptr[edi]
rcr ax,1
stosw ;zapis
jmp et_skp2 ;skok na konec
et_skp1:add edi,2 ;preskoc bod
et_skp2:add edx,4 ;dalsi pozice
dec ecx ;dokud nedosahneme praveho okraje obrazku
jnz et_lp3
et_end3:pop edx ;obnov vse ulozene
pop ecx
pop edi
pop esi ; +0
add ebp,4 ;dalsi y souradnice
sub edi,scr_linelen ;dalsi radka
cmp dword ptr [ebp],-1 ;test na konec tabulky
jnz et_lp4 ;jinak pokracuj
et_err: add esp,ed_stack;vymaz tabulku
pop ebp ;obnov ebp
}*/
}
void enemy_draw_mirror_transp(const void *src,void *trg,const void *shade,int scale,int maxspace,int clip)
//#pragma aux enemy_draw_mirror_transp parm[ESI][EDI][EBX][EDX][EAX][ECX]
{
int32_t scr_linelen2 = GetScreenPitch();
word *picinfo = (word *)src;
word *screen = (word *)trg;
int xtable[800];
int ytable[1200];
int xcount;
word pcx = picinfo[0];
word pcy = picinfo[1];
word type = picinfo[2];
unsigned char *picdata = (unsigned char *)src+(type == (512+8)?6:pic_start);
word *palette = (word *)shade;
int clipl = clip & 0xFFFF;
int clipr = clip >> 16;
int yiter;
if (maxspace >= 470) return;
//prepare ytable;
{
int rwofs = pcx*(pcy-1);
int accu = 0;
int *w = ytable;
int sp = maxspace*2;
while (sp > 0 && rwofs >= 0) {
*w++ = rwofs;
accu+=320;
while (accu >= scale && rwofs >= 0) {
accu-=scale;
rwofs-=pcx;
}
sp--;
}
*w++=-1;
//ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1
}
//prepare xtable
{
int *w = xtable;
int ofs = pcx-1;
int accu = 0;
while (ofs >= 0) {
*w++ = ofs;
accu+=320;
while (accu >= scale) {
accu-=scale;
ofs--;
}
}
xcount = w - xtable;
*w++=-1;
//xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1
}
if (clipl > xcount) return;
yiter = 0;
while (ytable[yiter] >= 0) {
int xiter = clipl;
int ofs = ytable[yiter];
unsigned char *row = picdata+ofs;
while (xiter < clipr && xtable[xiter] >= 0 ) {
int xpos = xiter -clipl;
unsigned char p = row[xtable[xiter]];
if (p != 0) {
if (p & 0x80) screen[xpos] = ((screen[xpos] & 0xF7DE) + (palette[p] & 0xF7DE))>>1;
else screen[xpos] = palette[p];
}
++xiter;
}
screen-=scr_linelen2;
++yiter;
}
/*
__asm
{
mov esi,src
mov edi,trg
mov ebx,shade
mov edx,scale
mov eax,maxspace
mov ecx,clip
push ebp
sub esp,ed_stack ;vyhrad zasobnik
mov ebp,esp
push ecx ;uchovej ecx +1
push edi ;uchovej edi +2
push ebx ;uchovej ebx +3
mov ebx,eax ;volne misto je ted v ebx
mov edi,ebp ;nastav edi na zacatek tabulek
push ebp ; +4
movzx ecx,short ptr[esi] ;precti xs
movzx eax,short ptr[esi+2] ;precti ys
imul eax,ecx ;xs*ys
sub eax,ecx ;minus 1 radek
xor ebp,ebp
etmlp1b:stosd ;zapis hodnotu do tabulky
add ebp,320 ;zmensovani
etmlp1a:cmp ebp,edx
jc etmnxt1 ;pri ebp<edx pokracuj dal
sub ebp,edx
sub eax,ecx ;odecti radku
jbe etmend1 ;pokud je to posledni tak konec1
jmp etmlp1a
etmnxt1:dec ebx
jnz etmlp1b
etmend1:xor eax,eax
dec eax
stosd ;tabulka pro y je hotova
pop ebp ; +3
lea edi,[ebp+ed_stk1] ;nastav se na druhou tabulku
xor ebx,ebx
movzx ecx,short ptr[esi] ;ecx je velikost obrazku v x
mov eax,ecx ;eax je velikost obrazku v x
dec eax
etmnxt2:stosd ;zapis x souradnici
add ebx,320 ;pocitej zmenseni
etmlp2a:cmp ebx,edx
jc etmnxt2
sub ebx,edx
sub eax,1
jnc etmlp2a
xor eax,eax
dec eax ;zapis -1 na konec tabulky
pop ebx ; +2
stosd
mov eax,edi ;konecnou pozici pro tabulku x zapis do eax
pop edi ;obnov registry edi exc ebx+1
cmp byte ptr [esi+5],2 ;obrazek bez palety?
jz etmpl1
add esi,pic_start;presun se na zacatek obrazku (za paletu)
jmp etmpl2
etmpl1: add esi,6 ;(obrazek bez palety, presun se za hlavicku)
etmpl2: pop ecx ; +0
movzx edx,cx ;vem levy okraj
lea edx,[ebp+edx*4]
lea edx,[edx+ed_stk1];edx ukazuje na sloupce
cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec
jbe etmerr
shr ecx,16 ;ecx ted obsahuje pravy okraj
etmlp4: push esi ;uchovej esi +1
push edi ;uchovej edi +2
add esi,[ebp] ;spocitej spravnou hodnotu esi
push ecx ;uchovej pravy okraj +3
push edx ;uchovej ukazatel na tabulku+4
etmlp3: mov eax,[edx]
cmp eax,-1 ;testuj konec tabulky
jz etmend3 ;pri pozitivnim vysledku => konec radky
movzx eax,byte ptr[esi+eax];vem barvu
test al,80h
jnz etmshd
or al,al
jz etmskp1 ;preskoc transparentni barvu
mov eax,[ebx+eax*2];vyzvedni hicolor
stosw ;zapis barvu
jmp etmskp2
etmshd: and short ptr[edi],0xF7DE
mov eax,[ebx+eax*2];vyzvedni hicolor
and eax,0xF7DE ;stmav
add ax,short ptr[edi]
rcr ax,1
stosw ;zapis
jmp etmskp2 ;skok na konec
etmskp1:add edi,2 ;preskoc bod
etmskp2:add edx,4 ;dalsi pozice
dec ecx ;dokud nedosahneme praveho okraje obrazku
jnz etmlp3
etmend3:pop edx ;obnov vse ulozene
pop ecx
pop edi
pop esi ; +0
add ebp,4 ;dalsi y souradnice
sub edi,scr_linelen ;dalsi radka
cmp dword ptr [ebp],-1 ;test na konec tabulky
jnz etmlp4 ;jinak pokracuj
etmerr: add esp,ed_stack;vymaz tabulku
pop ebp ;obnov ebp
}
*/
}
void enemy_draw_mirror(const void *src,void *trg,int shade,int scale,int maxspace,int clip)
//#pragma aux enemy_draw_mirror parm[ESI][EDI][EBX][EDX][EAX][ECX]
//clip je v poradi vpravo - vlevo (HiLo)
{
int32_t scr_linelen2 = GetScreenPitch();
word *picinfo = (word *)src;
word *screen = (word *)trg;
int xtable[800];
int ytable[1200];
int xcount;
word pcx = picinfo[0];
word pcy = picinfo[1];
unsigned char *picdata = (unsigned char *)src + pic_start;
word *palette = picinfo+shade/2;
int clipl = clip & 0xFFFF;
int clipr = clip >> 16;
int yiter;
if (maxspace >= 470) return;
//prepare ytable;
{
int rwofs = pcx*(pcy-1);
int accu = 0;
int *w = ytable;
int sp = maxspace*2;
while (sp > 0 && rwofs >= 0) {
*w++ = rwofs;
accu+=320;
while (accu >= scale && rwofs >= 0) {
accu-=scale;
rwofs-=pcx;
}
sp--;
}
*w++=-1;
//ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1
}
//prepare xtable
{
int *w = xtable;
int ofs = pcx-1;
int accu = 0;
while (ofs >= 0) {
*w++ = ofs;
accu+=320;
while (accu >= scale) {
accu-=scale;
ofs--;
}
}
xcount = w - xtable;
*w++=-1;
//xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1
}
if (clipl > xcount) return;
yiter = 0;
while (ytable[yiter] >= 0) {
int xiter = clipl;
int ofs = ytable[yiter];
unsigned char *row = picdata+ofs;
while (xiter < clipr && xtable[xiter] >= 0 ) {
int xpos = xiter;
unsigned char p = row[xtable[xiter]];
if (p != 0) {
if (p == 1) screen[xpos] = (screen[xpos] & 0xF7DE) >> 1;
else screen[xpos] = palette[p];
}
++xiter;
}
screen-=scr_linelen2;
++yiter;
}
/*
__asm
{
mov esi,src
mov edi,trg
mov ebx,shade
mov edx,scale
mov eax,maxspace
mov ecx,clip
push ebp
sub esp,ed_stack ;vyhrad zasobnik
mov ebp,esp
push ecx ;uchovej ecx +1
push edi ;uchovej edi +2
push ebx ;uchovej ebx +3
mov ebx,eax ;volne misto je ted v ebx
mov edi,ebp ;nastav edi na zacatek tabulek
push ebp ; +4
movzx ecx,short ptr[esi] ;precti xs
movzx eax,short ptr[esi+2] ;precti ys
imul eax,ecx ;xs*ys
sub eax,ecx ;minus 1 radek
xor ebp,ebp
edmlp1b:stosd ;zapis hodnotu do tabulky
add ebp,320 ;zmensovani
edmlp1a:cmp ebp,edx
jc edmnxt1 ;pri ebp<edx pokracuj dal
sub ebp,edx
sub eax,ecx ;odecti radku
jbe edmend1 ;pokud je to posledni tak konec1
jmp edmlp1a
edmnxt1:dec ebx
jnz edmlp1b
edmend1:xor eax,eax
dec eax
stosd ;tabulka pro y je hotova
pop ebp ; +3
lea edi,[ebp+ed_stk1] ;nastav se na druhou tabulku
xor ebx,ebx
movzx ecx,short ptr[esi] ;ecx je velikost obrazku v x
mov eax,ecx ;eax je velikost obrazku v x
dec eax
edmnxt2:stosd ;zapis x souradnici
add ebx,320 ;pocitej zmenseni
edmlp2a:cmp ebx,edx
jc edmnxt2
sub ebx,edx
sub eax,1
jnc edmlp2a
xor eax,eax
dec eax ;zapis -1 na konec tabulky
pop ebx ; +2
stosd
mov eax,edi ;konecnou pozici pro tabulku x zapis do eax
pop edi ;obnov registry edi exc ebx+1
add ebx,esi ;najdi adresu prekladove tabulky barev
add ebx,2 ;preskoc transparentni barvu
add esi,pic_start;presun se na zacatek obrazku
pop ecx ; +0
movzx edx,cx ;vem levy okraj
lea edx,[ebp+edx*4]
lea edx,[edx+ed_stk1];edx ukazuje na sloupce
cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec
jbe edmerr
shr ecx,16 ;ecx ted obsahuje pravy okraj
edmlp4: push esi ;uchovej esi +1
push edi ;uchovej edi +2
add esi,[ebp] ;spocitej spravnou hodnotu esi
push ecx ;uchovej pravy okraj +3
push edx ;uchovej ukazatel na tabulku+4
edmlp3: mov eax,[edx]
cmp eax,-1 ;testuj konec tabulky
jz edmend3 ;pri pozitivnim vysledku => konec radky
movzx eax,byte ptr[esi+eax];vem barvu
or al,al
jz edmskp1 ;preskoc transparentni barvu
dec al
jz edmshd ;1=shadow
mov eax,[ebx+eax*2];vyzvedni hicolor
stosw ;zapis barvu
jmp edmskp2
edmshd: movzx eax,short ptr[edi];vem barvu
and eax,0xF7DE ;stmav
shr eax,1
stosw ;zapis
jmp edmskp2 ;skok na konec
edmskp1:add edi,2 ;preskoc bod
edmskp2:add edx,4 ;dalsi pozice
dec ecx ;dokud nedosahneme praveho okraje obrazku
jnz edmlp3
edmend3:pop edx ;obnov vse ulozene
pop ecx
pop edi
pop esi ; +0
add ebp,4 ;dalsi y souradnice
sub edi,scr_linelen ;dalsi radka
cmp dword ptr [ebp],-1 ;test na konec tabulky
jnz edmlp4 ;jinak pokracuj
edmerr: add esp,ed_stack;vymaz tabulku
pop ebp ;obnov ebp
}
*/
}