/************************************************************************ * 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Ÿ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; }