kaos/KaosSrc/lgraph.cpp

1113 lines
17 KiB
C++
Raw Normal View History

2024-10-12 20:32:30 -05:00
/************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
************************************************************************/
// LGraph - Linear Graphics - (C)1997 NicoSo<53>t (Valentini Domenico)
#include "std.hpp"
#include "fixed.h"
#include "lgraph.hpp"
#include "io.h"
#include "fcntl.h"
void far *vbuff;
int lg_minx = 0, lg_miny = 0, lg_maxx = 319, lg_maxy = 199;
/*
#define xytodisp(_X,_Y) (_X+(_Y<<8)+(_Y<<6))
*/
#pragma warn -rvl
word xytodisp(word x, word y) {
asm {
MOV AX, y
XCHG AH, AL
MOV BX, AX
SHR BX, 2
ADD AX, BX
ADD AX, x
}}
#pragma warn +rvl
void setvrect(int x, int y, int dx, int dy) {
lg_minx = x; lg_miny = y;
lg_maxx = x+dx-1; lg_maxy = y+dy-1;
}
void initL() {
asm {
MOV AX, 0x0013
/*
MOV AX, 0x4F02
MOV BX, 0x0013
*/
INT 0x10
}}
void doneL() {
asm {
MOV AX, 0x0003
INT 0x10
}}
void setvbuff(void far *buff) {
vbuff = buff;
}
void putpix(word x, word y, byte col) {
asm {
LES DI, vbuff
MOV BX, y
XCHG BH, BL
MOV AX, BX
SHR AX, 2
ADD BX, AX
ADD BX, x
MOV AL, col
MOV ES:[DI+BX], AL
}}
#pragma warn -rvl
byte getpix(word x, word y) {
asm {
LES DI, vbuff
MOV BX, y
XCHG BH, BL
MOV AX, BX
SHR AX, 2
ADD BX, AX
ADD BX, x
MOV AL, ES:[DI+BX]
}}
#pragma warn +rvl
/*
void fillpage(byte col) {
asm {
LES DI, vbuff
MOV CX, 32000
MOV AL, col
MOV AH, AL
CLD
REP STOSW
}}
*/
void ffillscreen(long col) {
asm {
LES DI, vbuff
MOV CX, 16000
DB 0x66; MOV AX, WORD PTR col
CLD
DB 0x66
REP STOSW
}}
void ffillarea(word y, word dey, long col) {
asm {
LES DI, vbuff
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
MOV AX, dey
XCHG AH, AL
MOV CX, AX
SHR AX, 2
ADD CX, AX
SHR CX, 2
DB 0x66; MOV AX, WORD PTR col
CLD
DB 0x66
REP STOSW
}}
void ftransfscreen(void far *dest) {
asm {
//PUSH DS
LDS SI, vbuff
LES DI, dest
MOV CX, 16000
CLD
// CLI !
DB 0x66
REP MOVSW
// STI !
// !!! SS==DS !!!
MOV AX, SS
MOV DS, AX
//POP DS
}}
void ftransfarea(word y, word dey, void far *dest) {
asm {
//PUSH DS
LDS SI, vbuff
LES DI, dest
MOV AX, y
XCHG AH, AL
MOV BX, AX
SHR AX, 2
ADD BX, AX
ADD DI, BX
ADD SI, BX
MOV AX, dey
XCHG AH, AL
MOV CX, AX
SHR AX, 2
ADD CX, AX
SHR CX, 2
CLD
DB 0x66
REP MOVSW
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void fcopyarea(word y, word y1, word dey, void far *dest) {
asm {
//PUSH DS
LDS SI, vbuff
LES DI, dest
MOV AX, y1
XCHG AH, AL
MOV BX, AX
SHR AX, 2
ADD BX, AX
ADD DI, BX
MOV AX, y
XCHG AH, AL
MOV BX, AX
SHR AX, 2
ADD BX, AX
ADD SI, BX
MOV AX, dey
XCHG AH, AL
MOV CX, AX
SHR AX, 2
ADD CX, AX
SHR CX, 2
CLD
DB 0x66
REP MOVSW
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void ffillblock(word x, word y, word dex, word dey, long col) {
asm {
LES DI, vbuff
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV BX, 320
MOV DX, dex
ADD DX, 3
AND DX, 0xfffc
SUB BX, DX
SHR DX, 2
JZ end
DB 0x66; MOV AX, WORD PTR col
CLD
MOV CX, dey
PUSH BP
MOV BP, CX
} cic: asm {
MOV CX, DX
DB 0x66
REP STOSW
ADD DI, BX
DEC BP
JNZ cic
POP BP
} end:;}
void ftransfblock(word x, word y, word dex, word dey, void far *dest) {
asm {
LES DI, dest
MOV AX, y
XCHG AH, AL
MOV BX, AX
SHR BX, 2
ADD AX, BX
ADD AX, x
ADD DI, AX
MOV BX, 320
MOV DX, dex
ADD DX, 3
AND DX, 0xfffc
SUB BX, DX
SHR DX, 2
JZ end
//PUSH DS
LDS SI, vbuff
ADD SI, AX
CLD
MOV AX, dey
} cic: asm {
MOV CX, DX
DB 0x66
REP MOVSW
ADD SI, BX
ADD DI, BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV AX, SS
MOV DS, AX
//POP DS
} end:;}
void fcopyblock(word x, word y, word x1, word y1,
word dex, word dey, void far *dest) {
asm {
LES DI, dest
MOV AX, y1
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x1
MOV BX, 320
MOV DX, dex
ADD DX, 3
AND DX, 0xfffc
SUB BX, DX
SHR DX, 2
JZ end
//PUSH DS
LDS SI, vbuff
MOV AX, y
XCHG AH, AL
ADD SI, AX
SHR AX, 2
ADD SI, AX
ADD SI, x
CLD
MOV AX, dey
} cic: asm {
MOV CX, DX
DB 0x66
REP MOVSW
ADD SI, BX
ADD DI, BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
} end:;}
void getlfig(word x, word y, word dex, word dey, void far *data) {
//if (!(dex && dey)) return;
asm {
//PUSH DS
LDS SI, vbuff
LES DI, data
MOV AX, y
XCHG AH, AL
ADD SI, AX
SHR AX, 2
ADD SI, AX
ADD SI, x
MOV BX, 320
MOV DX, dex
SUB BX, DX
CLD
MOV AX, dey
} cic: asm {
MOV CX, DX
REP MOVSB
ADD SI, BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV AX, SS
MOV DS, AX
//POP DS
}}
// rotated
void getrfig(word x, word y, word dex, word dey, void far *data) {
// if (!(dex && dey)) return;
asm {
//PUSH DS
LDS SI, vbuff
LES DI, data
MOV AX, y
XCHG AH, AL
ADD SI, AX
SHR AX, 2
ADD SI, AX
ADD SI, x
MOV DX, dey
MOV BX, SI
CLD
MOV AX, dex
} cic: asm {
MOV CX, DX
MOV SI, BX
} cic1: asm {
MOVSB
ADD SI, 319
LOOP cic1
INC BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void storelfig(word x, word y, word dex, word dey, void far *data) {
asm {
//PUSH DS
LES DI, vbuff
LDS SI, data
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV BX, 320
MOV DX, dex
SUB BX, DX
CLD
MOV AX, dey
} cic: asm {
MOV CX, DX
REP MOVSB
ADD DI, BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void storerfig(word x, word y, word dex, word dey, void far *data) {
asm {
//PUSH DS
LES DI, vbuff
LDS SI, data
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV DX, dey
MOV BX, DI
CLD
MOV AX, dex
} cic: asm {
MOV CX, DX
MOV DI, BX
} cic1: asm {
MOVSB
ADD DI, 319
LOOP cic1
INC BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void putlfig(word x, word y, word dex, word dey, void far *data) {
asm {
//PUSH DS
LES DI, vbuff
LDS SI, data
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV BX, 320
MOV DX, dex
SUB BX, DX
CLD
MOV AX, dey
PUSH BP
MOV BP, AX
} cic: asm {
MOV CX, DX
} cic1: asm {
LODSB
OR AL, AL
JZ nopix
MOV ES:[DI], AL
} nopix: asm {
INC DI
LOOP cic1
ADD DI, BX
DEC BP
JNZ cic
POP BP
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void putrfig(word x, word y, word dex, word dey, void far *data) {
asm {
//PUSH DS
LES DI, vbuff
LDS SI, data
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV DX, dey
MOV BX, DI
CLD
MOV AX, dex
PUSH BP
MOV BP, AX
} cic: asm {
MOV CX, DX
MOV DI, BX
} cic1: asm {
LODSB
OR AL, AL
JZ nopix
MOV ES:[DI], AL
} nopix: asm {
ADD DI, 320
LOOP cic1
INC BX
DEC BP
JNZ cic
POP BP
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void putlchar(word x, word y, word dex, word dey,
byte col1, byte col2, void far *data) {
asm {
//PUSH DS
LES DI, vbuff
LDS SI, data
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV BX, 320
MOV DX, dex
SUB BX, DX
CLD
} cic: asm {
MOV CX, DX
} cic1: asm {
LODSB
OR AL, AL
JZ nopix
CMP AL, 1
JNE test2
MOV AL, col1
JMP store
} test2: asm {
CMP AL, 2
JNE store
MOV AL, col2
} store: asm {
MOV ES:[DI], AL
} nopix: asm {
INC DI
LOOP cic1
ADD DI, BX
DEC dey
JNZ cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void putlschar(word x, word y, word dex, word dey,
byte addcol, void far *data) {
asm {
//PUSH DS
LES DI, vbuff
LDS SI, data
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV BX, 320
MOV DX, dex
SUB BX, DX
CLD
MOV AH, addcol
MOV CX, dey
PUSH BP
MOV BP, CX
} cic: asm {
MOV CX, DX
} cic1: asm {
LODSB
OR AL, AL
JZ nopix
ADD AL, AH
MOV ES:[DI], AL
} nopix: asm {
INC DI
LOOP cic1
ADD DI, BX
DEC BP
JNZ cic
POP BP
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void getlvfig(int x, int y, word dex, word dey, void far *data) {
asm {
//PUSH DS
LDS SI, vbuff
LES DI, data
MOV AX, y // vale anche per negativi !
SAL AX, 6
MOV BX, AX
SAL BX, 2
ADD AX, BX
ADD AX, x
ADD SI, AX
MOV BX, 320
MOV DX, dex
SUB BX, DX
CLD
MOV AX, dey
} cic: asm {
MOV CX, DX
REP MOVSB
ADD SI, BX
DEC AX
JNZ cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void storelcfig(int x, int y, word dex, word dey, void far *data) {
int vdx, minx, miny, maxy;
word savesi;
if (x+dex<=lg_minx || y+dey<=lg_miny) return;
if (x+dex>lg_maxx) vdx = lg_maxx-x+1;
else vdx = dex;
if (vdx<=0) return;
minx = lg_minx;
miny = lg_miny; maxy = lg_maxy;
asm {
LES DI, vbuff
LDS SI, data
MOV AX, y
SAL AX, 6
MOV BX, AX
SAL BX, 2
ADD AX, BX
ADD AX, x
ADD DI, AX
//CLD no MOVS o LODS
MOV savesi, SI
MOV DX, DI
MOV BX, dey
} cic: asm {
MOV AX, y
CMP AX, miny
JL passy
CMP AX, maxy
JG end
MOV SI, savesi
MOV DI, DX
MOV CX, vdx
} cic1: asm {
MOV AX, x
CMP AX, minx
JL nopix
MOV AL, [SI]
MOV ES:[DI], AL
} nopix: asm {
INC SI
INC DI
INC x
LOOP cic1
MOV AX, vdx
SUB x, AX
} passy: asm {
MOV AX, dex
ADD savesi, AX
ADD DX, 320
INC y
DEC BX
JNZ cic
} end: asm {
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void putlcfig(int x, int y, word dex, word dey, void far *data) {
int vdx, minx, miny, maxy;
word savesi;
if (x+dex<=lg_minx || y+dey<=lg_miny) return;
if (x+dex>lg_maxx) vdx = lg_maxx-x+1;
else vdx = dex;
if (vdx<=0) return;
minx = lg_minx;
miny = lg_miny; maxy = lg_maxy;
asm {
LES DI, vbuff
LDS SI, data
MOV AX, y
SAL AX, 6
MOV BX, AX
SHL BX, 2
ADD AX, BX
ADD AX, x
ADD DI, AX
/*
XCHG AH, AL
ADD DI, AX
SAR AX, 2
ADD DI, AX
ADD DI, x
*/
// CLD no MOVS o LODS
MOV savesi, SI
MOV DX, DI
MOV BX, dey
} cic: asm {
MOV AX, y
CMP AX, miny
JL passy
CMP AX, maxy
JG end
MOV SI, savesi
MOV DI, DX
MOV CX, vdx
} cic1: asm {
MOV AX, x
CMP AX, minx
JL nopix
MOV AL, [SI]
OR AL, AL
JZ nopix
MOV ES:[DI], AL
} nopix: asm {
INC SI
INC DI
INC x
LOOP cic1
MOV AX, vdx
SUB x, AX
} passy: asm {
MOV AX, dex
ADD savesi, AX
ADD DX, 320
INC y
DEC BX
JNZ cic
} end: asm {
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void putlcchar(int x, int y, word dex, word dey,
byte col1, byte col2, void far *data) {
int vdx, minx, miny, maxy;
word savesi;
if (x+dex<=lg_minx || y+dey<=lg_miny) return;
if (x+dex>lg_maxx) vdx = lg_maxx-x+1;
else vdx = dex;
if (vdx<=0) return;
minx = lg_minx;
miny = lg_miny; maxy = lg_maxy;
asm {
LES DI, vbuff
LDS SI, data
MOV AX, y
SAL AX, 6
MOV BX, AX
SHL BX, 2
ADD AX, BX
ADD AX, x
ADD DI, AX
/*
XCHG AH, AL
ADD DI, AX
SAR AX, 2
ADD DI, AX
ADD DI, x
*/
// CLD no MOVS o LODS
MOV savesi, SI
MOV DX, DI
MOV BX, dey
} cic: asm {
MOV AX, y
CMP AX, miny
JL passy
CMP AX, maxy
JG end
MOV SI, savesi
MOV DI, DX
MOV CX, vdx
} cic1: asm {
MOV AX, x
CMP AX, minx
JL nopix
MOV AL, [SI]
OR AL, AL
JZ nopix
CMP AL, 1
JNE test2
MOV AL, col1
JMP store
} test2: asm {
CMP AL, 2
JNE store
MOV AL, col2
} store: asm {
MOV ES:[DI], AL
} nopix: asm {
INC SI
INC DI
INC x
LOOP cic1
MOV AX, vdx
SUB x, AX
} passy: asm {
MOV AX, dex
ADD savesi, AX
ADD DX, 320
INC y
DEC BX
JNZ cic
} end: asm {
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
void storelmfig(word x, word y, word dex, word dey,
void far *mask, void far *data) {
int displ, cnt;
asm {
//PUSH DS
LES DI, vbuff
LDS SI, mask
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
ADD DI, x
MOV AX, 320
SUB AX, dex
MOV displ, AX
// CLD no MOVS o LODS
XOR BX, BX
MOV DX, dey
} cic: asm {
MOV CX, dex
} cici: asm {
CMP BYTE PTR [SI+BX], 0
JE nopix
LDS SI, data
MOV AL, [SI+BX]
MOV ES:[DI], AL
LDS SI, mask
} nopix: asm {
INC DI
INC BX
LOOP cici
ADD DI, displ
DEC DX
JNZ cic
// !!! SS==DS !!!
MOV AX, SS
MOV DS, AX
//POP DS
}}
void scalerscfig(int x, int y, word dex, word dey, int vdx, int vdy,
char shade, void far *rfig) {
word savedi, totresx, left = lg_minx, right = lg_maxx;
fixed adjy, adjx, adjo;
if (!rfig) return;
asm {
XOR AX, AX
MOV WORD PTR adjx, AX
MOV WORD PTR adjy, AX
MOV AX, dex
MOV WORD PTR adjx[2], AX
MOV AX, dey
MOV WORD PTR adjy[2], AX
}
adjx = fixdiv(adjx,vdx);
adjy = fixdiv(adjy,vdy);
if (y < lg_miny) {
adjo = adjy * (lg_miny-y);
vdy += y;
y = lg_miny;
} else adjo = 0l;
if (y+vdy-1>lg_maxy) vdy = lg_maxy+1-y;
if (vdy<=0) return; // !!! serve ?
asm {
//PUSH DS
MOV totresx, 0
MOV AX, WORD PTR adjx[2]
OR AX, AX
JZ nomul
MOV BX, dey
MUL BX
MOV WORD PTR adjx[2], AX
} nomul: asm {
LES DI, vbuff
/*
MOV AX, 0xA000
MOV ES, AX
XOR DI, DI
*/
MOV AX, y
XCHG AH, AL
ADD DI, AX
SHR AX, 2
ADD DI, AX
MOV BX, x
ADD DI, BX
LDS SI, rfig // !!!
// CLD no MOVS o LODS
MOV CX, vdx
JCXZ end // !!! serve ?
MOV savedi, DI
} ini: asm {
PUSH CX
MOV BX, x
CMP BX, left
// JL clipx
JGE gomax
JMP clipx
} gomax: asm {
CMP BX, right
// JG hardend
JLE gomask
JMP hardend
} gomask: asm {
MOV DI, savedi
MOV SI, WORD PTR rfig
MOV CX, vdy
ADD SI, WORD PTR adjo[2]
MOV DX, WORD PTR adjo
MOV BX, WORD PTR adjy[2]
} draw: asm {
MOV AL, [SI]
OR AL, AL
JZ noplot
// Shader
MOV AH, AL
ADD AL, shade
XOR AH, AL
AND AH, 0xf0/*HISHMASK*/
JZ store
XOR AL, AH
OR AL, 0x0f/*LOSHMASK*/
} store: asm {
MOV ES:[DI], AL
} noplot: asm {
ADD DI, 320
ADD DX, WORD PTR adjy
ADC SI, BX
LOOP draw
} clipx: asm {
MOV AX, WORD PTR adjx[2]
ADD WORD PTR rfig, AX
MOV AX, WORD PTR adjx
ADD totresx, AX
JNC nocar
MOV AX, dey
ADD WORD PTR rfig, AX
} nocar: asm {
INC x
INC savedi
POP CX
DEC CX
JZ end
JMP ini
} hardend: asm {
POP CX
} end: asm {
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}}
#pragma warn -rvl
int near swapb(int n) {
asm {
MOV AX, n
XCHG AL, AH
}}
#pragma warn +rvl
char loadLBM(const char *filename, void far *pal) {
int handle;
form_chunk fchunk;
chunk_header chunkhead;
bitmap_header bmhead;
int rest, len, height;
char data;
char far *pbuf = (char *)vbuff;
if ((handle = _open(filename,O_RDONLY|O_BINARY)) != -1) {
_read(handle,&fchunk,sizeof(form_chunk));
if (fchunk.ID_type != CK_FORM) {
_close(handle);
// error("loadLBM - Invalid format");
return 0;
}
if (fchunk.ID_subtype != ID_PBM) {
_close(handle);
// error("loadLBM - Not a PBM IFF file");
return 0;
}
while (!eof(handle)) {
_read(handle,&chunkhead,sizeof(chunk_header));
asm {
MOV DX, WORD PTR chunkhead.cksize
MOV AX, WORD PTR chunkhead.cksize[2]
XCHG AL, AH
XCHG DL, DH
INC AX
ADC DX, 0
AND AL, 0xfe
MOV WORD PTR chunkhead.cksize, AX
MOV WORD PTR chunkhead.cksize[2], DX
}
if (chunkhead.ID_chunk == ID_BMHD) {
_read(handle,&bmhead,sizeof(bitmap_header));
bmhead.width = swapb(bmhead.width);
bmhead.height = swapb(bmhead.height);
} else
if (chunkhead.ID_chunk == ID_CMAP) {
if (pal) {
_read(handle,pal,768); // DEVE essere 768 !
asm {
//PUSH DS
LDS SI, pal
LES DI, pal
MOV CX, 384
CLD
} cic: asm {
LODSW
SHR AL, 2
SHR AH, 2
STOSW
LOOP cic
// !!! SS==DS !!!
MOV BX, SS
MOV DS, BX
//POP DS
}
} else lseek(handle,768,SEEK_CUR);
} else
if (chunkhead.ID_chunk == ID_BODY) {
for (height = bmhead.height; height; height--) {
rest = (bmhead.width+1) & 0x7ffe;
if (bmhead.compression) {
while (rest) {
_read(handle,&data,1);
if (data>0) {
rest -= (len = data+1);
if (_read(handle,pbuf,len) == -1) {
_close(handle);
// error("loadLBM - invalid file");
return 0;
}
pbuf+=len;
} else {
rest -= (len = (-data)+1);
_read(handle,&data,1);
asm {
LES DI, pbuf
CLD
MOV AL, data
MOV AH, AL
MOV CX, len
SHR CX, 1
JNC pari
STOSB
} pari: asm {
REP STOSW
MOV WORD PTR pbuf, DI
MOV WORD PTR pbuf[2], ES
}
}
}
} else _read(handle,pbuf,rest);
}
} else lseek(handle,chunkhead.cksize,SEEK_CUR);
}
_close(handle);
return 1;
}
return 0;
}