#include "alloc.h" #include "io.h" #include "fcntl.h" #include "conio.h" #include "sys/stat.h" /*The following are the prototypes for the routine sin FADE.ASM */ void setPal(void far *pal); void fill_pal(void far *pal,char red,char green,char blue); void copy_pal(void far *pal,void far *pal_dest); void sub_palette(void far *pal,void far *pal_dest); void fade_between_once(void far *pal,void far *pal_dest); char pal[768]; char pal2[768]; const char *image="image.raw"; const char *palf1="pal1.pal"; const char *palf2="pal2.pal"; int readstuff(const char *filename,void far *buf,unsigned length) { int handle, bytes; if ((handle = sopen(filename, O_RDONLY | O_BINARY, S_IWRITE | S_IREAD)) == -1) { printf("Error Opening File\n"); exit(1); } if ((bytes = read(handle, buf, length)) == -1) { printf("Read Failed.\n"); exit(1); } return 0; } void fade_between_screen(void far *pal,void far *paldest) /* This routine actually morph one palette to another */ { int n; char far *buff,*buff2; buff=farmalloc(768*2); buff2=farmalloc(768); copyPal(paldest,buff2); copyPal(pal,buff); sub_palette(buff,buff2); for(n=0;n<63;++n) fade_between_once(buff,buff2); farfree(buff2); farfree(buff); } void main() { int n; asm{ /* set mode 13h video mode*/ mov ax,13h int 10h } /* read 320*200 raw image to video buffer*/ fill_pal(&pal,0,0,0); /* fill pal[768] with 0*/ setPal(&pal); readstuff(image,(void far *)0xa0000000,64000); /*read palette file */ readstuff(palf1,&pal,768); readstuff(palf2,&pal2,768); setPal(&pal); getch(); fade_between_screen(&pal,&pal2); getch(); fade_between_screen(&pal2,&pal); getch(); asm{ /* return to text mode */ mov ax,3h int 10h } printf("crosfade.exe written by Esak 1994"); } %TITLE "moduleShell" ;--------------------------------------------------------------------- ; CAUTION! ; This module is written in Ideal model, meaning you need ; Borland Turbo Assembler to compile it. ;------------------------------------------------------------------------ IDEAL P286 include "model.inc" DATASEG PAL_SIZE EQU 768 CODESEG PUBLIC _setpal PUBLIC _sub_palette,_fade_between_once PUBLIC _fill_pal,_copyPal PROC _setpal ;----------------------------------------------------------------- ; void setpal(void far *pal) ; This function simply updates hardware palette using the data ; stored in char pal[PAL_SIZE] ; (PAL_SIZE=768) ;----------------------------------------------------------------- ARG pal:dword push bp mov bp,sp push ds push di push si lds si,[pal] call SETPAL pop si pop di pop ds pop bp ret ENDP _setpal PROC _sub_palette ;---------------------------------------------------------------------- ; sub_palette(void *pal,void far *pal_dest) ; This routine prepares the palettes for fade_between_once() ; function. ; WARNING: pal points to char array of 768*2 bytes, not 768 bytes ;---------------------------------------------------------------------- ARG pal:dword,pal_dest:dword push bp mov bp,sp push ds push di push si lds si,[pal] ;ds:si points to pal[] les di,[pal_dest] ;es:di points to pal_dest[] mov cx,PAL_SIZE ; the following loop is basically @@l: lodsb ; for(n=0;n<768;++n) sub [es:di],al ; pal_dest[n]=pal_dest[n]-pal[n]; inc di ; loop @@l mov cx,PAL_SIZE/2 ; the following loop is equivalent to xor ax,ax @@l2: mov [ds:si],ax ; for(n=0;n<768;++n) inc si ; pal[n+PAL_SIZE]=0; inc si loop @@l2 pop si pop di pop ds pop bp ret ENDP _sub_palette PROC _fade_between_once ;------------------------------------------------------------------- ; fade_between_once(void far *pal,void far *pal_dest) ; call sub_palette first ; Which will destroy original values of pal_dest, ; but it's a necessary step. ; After calling it 63 times,the content of pal[768] will become ; identical to the original values of pal_dest anyway :) ;------------------------------------------------------------------- ARG pal:dword,pal_dest:dword push bp mov bp,sp push ds push di push si lds si,[pal] les di,[pal_dest] cld push si mov cx,PAL_SIZE fl2: ; increase the value of pallettes mov bl,[es:di] ; es:di = dest_pal cmp bl,0 jl fl4 ; if bl>0 then goto fl4 add [PAL_SIZE+si],bl jmp fl3 fl4: neg bl add [PAL_SIZE+si],bl fl5: cmp [byte ptr PAL_SIZE+si],63 jb fl7 dec [byte ptr si] sub [byte ptr PAL_SIZE+si],63 jmp fl7 fl3: cmp [byte ptr PAL_SIZE+si],63 jb fl7 ; inc [byte ptr si] ; increase by one sub [byte ptr PAL_SIZE+si],63 fl7: inc di inc si loop fl2 pop si call Setpal pop si pop di pop ds pop bp ret ENDP _fade_between_once ;------------------------------------------------------------------------- ; update the hardware palette ; input: ds:si points to palette array ;------------------------------------------------------------------------- PROC SETPAL mov bh,0 ; bh=# of the first palette color to ; update. mov bl,2 ;This is the loop index. ;In the following codes, we are updating ;128 color at a time. Therefore, we need ;a loop that runs twice in order to update ;all 256 colors. mov cx,128*3 ; di=128(the number of colors to update)*3 PROC SETPAL2 s: mov dx, 03DAh ; CRT controller input status 1 register v1: in al, dx test al,08h jnz v1 ; wait until vertical retrace starts v2: in al, dx test al,08h ; wait until vertical retrace ends jz v2 ;--------- We have done waiting. Now let's update the palette mov al,bh ; get first color # to process into al mov dx, 03c8h ; DAC palette index register push cx out dx, al ; Write the register number to the dac inc dx rep outsb pop cx add bh,128 ; color index=color index+128 dec bl jnz s ret ;---------------------------------------- ENDP SETPAL2 PROC _fill_pal ;------------------------------------------------------------- ; fill_pal(void far *pal, char red, char green, char blue); ; fills the palette array with the color data given ; does not update hardware palette ;------------------------------------------------------------- ARG pal:dword, red:byte, green:byte,blue:byte push bp mov bp,sp push di les di,[pal] cld mov cx,PAL_SIZE/3 mov al,[red] mov ah,[green] mov bl,[blue] @@fpl:mov [es:di],al mov [es:di+1],ah mov [es:di+2],bl add di,3 loop @@fpl pop di pop bp ret ENDP _fill_pal PROC _copyPal ;---------------------------------------------------------------- ; copyPal(void far *source,void far *dest:dword) ; ; both *source and *dest points to arrays of 768 bytes (chars) ; I know there are C functions out there to copy strings. But ; I wrote this anyway. What the heck, it only took me a minute. ;---------------------------------------------------------------- ARG source:dword,dest:dword push bp mov bp,sp push ds push di push si cld les di,[dest] lds si,[source] mov cx,PAL_SIZE rep movsb pop si pop di pop ds pop bp ret ENDP _copyPal END ; End of module