1 ;; Palette operations
\r
2 ;; Note that where needed in the macros, a "palette" refers to
\r
3 ;; the segment handle to a 768-byte piece of memory. So palettes
\r
4 ;; can be loaded and freed, they're not permanent, but if you want
\r
5 ;; to use a fixed (not allocated) palette you'd better make sure
\r
6 ;; it's segment aligned or else you can't use these macros. If it
\r
7 ;; is, you can just supply "seg myPalette" as the 'palette' argument
\r
8 ;; to any of these macros.
\r
10 ;; Fade from a palette to black
\r
11 FADE_OFF MACRO fade,palette
\r
14 mov bh,fade ; positive -> Gets dimmer...
\r
15 mov bl,0 ; Starts exact
\r
16 mov cx,64/fade+1 ; Total number of loops required
\r
20 ;; Fade from black to a palette
\r
21 FADE_ON MACRO fade,palette
\r
24 mov bh,-fade ; negative -> Gets brighter...
\r
25 mov bl,64 ; Starts totally dimmed
\r
26 mov cx,64/fade+1 ; Total number of loops required
\r
30 ;; Flash from a palette to white
\r
31 FLASH_OFF MACRO fade,palette
\r
34 mov bh,-fade ; negative -> gets brighter
\r
35 mov bl,0 ; Starts exact
\r
36 mov cx,64/fade+1 ; Total number of loops required
\r
40 ;; Flash from white to a palette
\r
41 FLASH_ON MACRO fade,palette
\r
44 mov bh,fade ; positive -> Gets dimmer...
\r
45 mov bl,-64 ; Starts totally bright
\r
46 mov cx,64/fade+1 ; Total number of loops required
\r
50 ;; Save a palette into a palette-sized piece of memory
\r
51 PAL_SAVE MACRO palette
\r
57 ; Returns AX = a new segment for a palette
\r
58 NEW_PAL MACRO palette
\r
59 mov bx,(256 * 3) / 16
\r
65 ;; Black the entire palette temporarily. Used to blank the screen while
\r
66 ;; drawing a frame before fading in.
\r
70 mov si,OFFSET tmppal
\r
71 mov bh,-1 ; Doesn't really matter...
\r
72 mov bl,64 ; Starts totally dimmed
\r
73 mov cx,1 ; Just one time -- to leave it black
\r
77 ;; drawing a frame before fading in.
\r
81 mov si,OFFSET tmppal
\r
82 mov bh,-1 ; Doesn't really matter...
\r
83 mov bl,-64 ; Starts totally dimmed
\r
84 mov cx,1 ; Just one time -- to leave it black
\r
88 ;; Black the entire palette temporarily. Used to blank the screen while
\r
89 ;; drawing a frame before fading in.
\r
91 mov cx,0 ; 0 times = update
\r
97 mov dx,INPUT_STATUS_1
\r
107 ;; The following code is modified greatly from the Future Crew's palette
\r
108 ;; fading code. Works on blocks of 256 colors only, so far, but I might
\r
109 ;; change it later. Also, it theoretically could "anti-fade" -- fade to
\r
110 ;; white -- which I call flashing, so I added that ability, which was
\r
111 ;; missing from FC's code.
\r
113 tmppal DB 768 dup (?) ; Stores old palette
\r
114 FadePalette PROC NEAR
\r
124 ; Load in the colors in the palette
\r
125 mov di,OFFSET tmppal ; ES:DI -> temp palette
\r
126 mov cx,768 ; Reads 256*3 bytes at a time.
\r
127 loadpal_loop: mov al,ds:[si] ; Load one color byte
\r
129 sub al,bl ; Subtract the fade amount
\r
130 jge pal_more ; Limit the range by clipping
\r
131 xor al,al ; to between 0 and 63
\r
132 jmp pal_ok ; (there's probably a faster
\r
133 pal_more: cmp al,63 ; way to do it than this,
\r
134 jle pal_ok ; but I don't know it)
\r
136 pal_ok: mov es:[di],al ; Store that byte in the new
\r
138 dec cx ; temp palette and loop.
\r
141 ; Get ready to move this block of palette values
\r
142 JustUpdate: sti ; Let interrupts happen now,
\r
143 WAITBORDER ; while waiting for a retrace,
\r
144 cli ; instead of more critical times
\r
146 mov dx,PEL_WRITE_REG; Set up to write to color register,
\r
147 xor al,al ; starting at palette entry 0.
\r
149 mov dx,PEL_DATA_REG ; Point at color port
\r
151 ; Quickly put out the first half of the color palette
\r
152 mov di,OFFSET tmppal
\r
153 mov cl,(768/6)/2 ; Does 2 loops of 128 colors each.
\r
154 cli ; Waits a retrace inbetween...
\r
155 FirstHalfLoop: REPEAT 6 ; Steps of 6 -- reduces the
\r
156 mov al,es:[di] ; number of LOOP instructions
\r
164 WAITBORDER ; Waits one retrace -- less flicker
\r
165 mov dx,PEL_DATA_REG ; Reset DX
\r
167 ; Now, quickly put out the other half of the colors.
\r
170 SecondHalfLoop: REPEAT 6 ; Steps of 6 -- reduces the
\r
171 mov al,es:[di] ; number of LOOP instructions
\r
178 ; For the next iteration, restore everything and loop
\r
185 add bl,bh ; Change brightness by BH
\r
190 ; All done, re-enable interrupts and return
\r
195 ;; Saves the palette into the memory pointed at by DS:SI. That memory
\r
196 ;; must be at least 768 bytes long...
\r
197 SavePalette PROC NEAR
\r
198 mov dx,PEL_READ_REG ; Set up to read from color register,
\r
199 xor al,al ; starting at palette entry 0.
\r
201 mov dx,PEL_DATA_REG
\r
203 ; Quickly read in the first half of the color palette
\r
206 ReadPalLoop: REPEAT 6 ; Steps of 6 -- reduces the
\r
207 in al,dx ; number of LOOP instructions
\r
213 ; All done, re-enable interrupts and return
\r
218 ;; Load a palette from a file. Opens the file and reads it into
\r
219 ;; memory (standard LoadFile) and then points the palette at that
\r
220 ;; newly allocated memory. Also, frees old memory before it does
\r
222 LoadPaletteFile PROC near
\r
233 pal_not_loaded: call LoadFile
\r
238 LoadPaletteFile ENDP
\r