]> 4ch.mooo.com Git - 16.git/blobdiff - 16/scrasm/PALETTE.INC
refresh wwww
[16.git] / 16 / scrasm / PALETTE.INC
diff --git a/16/scrasm/PALETTE.INC b/16/scrasm/PALETTE.INC
new file mode 100755 (executable)
index 0000000..e3bd381
--- /dev/null
@@ -0,0 +1,239 @@
+;; Palette operations\r
+;; Note that where needed in the macros, a "palette" refers to\r
+;; the segment handle to a 768-byte piece of memory.  So palettes\r
+;; can be loaded and freed, they're not permanent, but if you want\r
+;; to use a fixed (not allocated) palette you'd better make sure\r
+;; it's segment aligned or else you can't use these macros.  If it\r
+;; is, you can just supply "seg myPalette" as the 'palette' argument\r
+;; to any of these macros.\r
+\r
+;; Fade from a palette to black\r
+FADE_OFF        MACRO   fade,palette\r
+                mov     si,0\r
+                mov     ds,palette\r
+                mov     bh,fade         ; positive -> Gets dimmer...\r
+                mov     bl,0            ; Starts exact\r
+                mov     cx,64/fade+1    ; Total number of loops required\r
+                call    FadePalette\r
+                ENDM\r
+\r
+;; Fade from black to a palette\r
+FADE_ON         MACRO   fade,palette\r
+                mov     si,0\r
+                mov     ds,palette\r
+                mov     bh,-fade        ; negative -> Gets brighter...\r
+                mov     bl,64           ; Starts totally dimmed\r
+                mov     cx,64/fade+1    ; Total number of loops required\r
+                call    FadePalette\r
+                ENDM\r
+\r
+;; Flash from a palette to white\r
+FLASH_OFF       MACRO   fade,palette\r
+                mov     si,0\r
+                mov     ds,palette\r
+                mov     bh,-fade        ; negative -> gets brighter\r
+                mov     bl,0            ; Starts exact\r
+                mov     cx,64/fade+1    ; Total number of loops required\r
+                call    FadePalette\r
+                ENDM\r
+\r
+;; Flash from white to a palette\r
+FLASH_ON        MACRO   fade,palette\r
+                mov     si,0\r
+                mov     ds,palette\r
+                mov     bh,fade         ; positive -> Gets dimmer...\r
+                mov     bl,-64          ; Starts totally bright\r
+                mov     cx,64/fade+1    ; Total number of loops required\r
+                call    FadePalette\r
+                ENDM\r
+\r
+;; Save a palette into a palette-sized piece of memory\r
+PAL_SAVE        MACRO   palette\r
+                mov     es,palette\r
+                mov     di,0\r
+                call    SavePalette\r
+                ENDM\r
+\r
+; Returns AX = a new segment for a palette\r
+NEW_PAL         MACRO   palette\r
+                mov     bx,(256 * 3) / 16\r
+                mov     ah,48h\r
+                int     21h\r
+                mov     palette,ax\r
+                ENDM\r
+\r
+;; Black the entire palette temporarily.  Used to blank the screen while\r
+;; drawing a frame before fading in.\r
+PAL_BLACK       MACRO\r
+                mov     ax,seg tmppal\r
+                mov     ds,ax\r
+                mov     si,OFFSET tmppal\r
+                mov     bh,-1           ; Doesn't really matter...\r
+                mov     bl,64           ; Starts totally dimmed\r
+                mov     cx,1            ; Just one time -- to leave it black\r
+                call    FadePalette\r
+                ENDM\r
+\r
+;; drawing a frame before fading in.\r
+PAL_WHITE       MACRO\r
+                mov     ax,seg tmppal\r
+                mov     ds,ax\r
+                mov     si,OFFSET tmppal\r
+                mov     bh,-1           ; Doesn't really matter...\r
+                mov     bl,-64          ; Starts totally dimmed\r
+                mov     cx,1            ; Just one time -- to leave it black\r
+                call    FadePalette\r
+                ENDM\r
+\r
+;; Black the entire palette temporarily.  Used to blank the screen while\r
+;; drawing a frame before fading in.\r
+PAL_UPDATE      MACRO\r
+                mov     cx,0            ; 0 times = update\r
+                call    FadePalette\r
+                ENDM\r
+\r
+WAITBORDER      MACRO\r
+                LOCAL   wbr1,wbr2\r
+                mov     dx,INPUT_STATUS_1\r
+wbr1:           in      al,dx\r
+                test    al,8\r
+                jnz     wbr1\r
+wbr2:           in      al,dx\r
+                test    al,8\r
+                jz      wbr2\r
+                ENDM\r
+\r
+;; Fade Palette:\r
+;; The following code is modified greatly from the Future Crew's palette\r
+;; fading code.  Works on blocks of 256 colors only, so far, but I might\r
+;; change it later.  Also, it theoretically could "anti-fade" -- fade to\r
+;; white -- which I call flashing, so I added that ability, which was\r
+;; missing from FC's code.\r
+EVEN\r
+tmppal          DB      768 dup (?)      ; Stores old palette\r
+FadePalette     PROC NEAR\r
+                mov     ax,seg tmppal\r
+                mov     es,ax\r
+\r
+FadeLoop:       push    cx\r
+                push    si\r
+\r
+                cmp     cx,0\r
+                je      JustUpdate\r
+\r
+        ; Load in the colors in the palette\r
+                mov     di,OFFSET tmppal ; ES:DI -> temp palette\r
+                mov     cx,768          ; Reads 256*3 bytes at a time.\r
+loadpal_loop:   mov     al,ds:[si]      ; Load one color byte\r
+                inc     si\r
+                sub     al,bl           ; Subtract the fade amount\r
+                jge     pal_more        ; Limit the range by clipping\r
+                xor     al,al           ;  to between 0 and 63\r
+                jmp     pal_ok          ; (there's probably a faster\r
+pal_more:       cmp     al,63           ; way to do it than this,\r
+                jle     pal_ok          ; but I don't know it)\r
+                mov     al,63\r
+pal_ok:         mov     es:[di],al      ; Store that byte in the new\r
+                inc     di\r
+                dec     cx              ;  temp palette and loop.\r
+                jnz     loadpal_loop\r
+\r
+        ; Get ready to move this block of palette values\r
+JustUpdate:     sti                     ; Let interrupts happen now,\r
+                WAITBORDER              ;  while waiting for a retrace,\r
+                cli                     ;  instead of more critical times\r
+\r
+                mov     dx,PEL_WRITE_REG; Set up to write to color register,\r
+                xor     al,al           ; starting at palette entry 0.\r
+                out     dx,al\r
+                mov     dx,PEL_DATA_REG ; Point at color port\r
+\r
+        ; Quickly put out the first half of the color palette\r
+                mov     di,OFFSET tmppal\r
+                mov     cl,(768/6)/2    ; Does 2 loops of 128 colors each.\r
+                cli                     ;  Waits a retrace inbetween...\r
+FirstHalfLoop:  REPEAT 6                ; Steps of 6 -- reduces the\r
+                mov     al,es:[di]      ; number of LOOP instructions\r
+                inc     di\r
+                out     dx,al\r
+                ENDM\r
+                dec     cl\r
+                jnz     FirstHalfLoop\r
+                sti\r
+\r
+                WAITBORDER              ; Waits one retrace -- less flicker\r
+                mov     dx,PEL_DATA_REG ; Reset DX\r
+\r
+        ; Now, quickly put out the other half of the colors.\r
+                mov     cl,(768/6)/2\r
+                cli\r
+SecondHalfLoop: REPEAT 6                ; Steps of 6 -- reduces the\r
+                mov     al,es:[di]      ; number of LOOP instructions\r
+                inc     di\r
+                out     dx,al\r
+                ENDM\r
+                dec     cl\r
+                jnz     SecondHalfLoop\r
+\r
+        ; For the next iteration, restore everything and loop\r
+                pop     si\r
+                pop     cx\r
+\r
+                cmp     cx,0\r
+                je      JustUpdated\r
+\r
+                add     bl,bh           ; Change brightness by BH\r
+\r
+                dec     cx\r
+                jnz     FadeLoop\r
+\r
+        ; All done, re-enable interrupts and return\r
+JustUpdated:    sti\r
+                ret\r
+FadePalette     ENDP\r
+\r
+;; Saves the palette into the memory pointed at by DS:SI.  That memory\r
+;; must be at least 768 bytes long...\r
+SavePalette     PROC NEAR\r
+                mov     dx,PEL_READ_REG ; Set up to read from color register,\r
+                xor     al,al           ; starting at palette entry 0.\r
+                out     dx,al\r
+                mov     dx,PEL_DATA_REG\r
+\r
+        ; Quickly read in the first half of the color palette\r
+                mov     cl,(768/6)\r
+                cli\r
+ReadPalLoop:    REPEAT 6                ; Steps of 6 -- reduces the\r
+                in      al,dx           ; number of LOOP instructions\r
+                mov     es:[di],al\r
+                inc     di\r
+                ENDM\r
+                dec     cl\r
+                jnz     ReadPalLoop\r
+        ; All done, re-enable interrupts and return\r
+                sti\r
+                ret\r
+SavePalette     ENDP\r
+\r
+;; Load a palette from a file.  Opens the file and reads it into\r
+;; memory (standard LoadFile) and then points the palette at that\r
+;; newly allocated memory.  Also, frees old memory before it does\r
+;; any loading ...\r
+LoadPaletteFile PROC    near\r
+                mov     ax,segPalette\r
+                cmp     ax,-1\r
+                je      pal_not_loaded\r
+                mov     es,ax\r
+                mov     ah,49h\r
+                int     21h\r
+                mov     nError,ERR_MEM\r
+                jc      lp_err\r
+                mov     segPalette,-1\r
+\r
+pal_not_loaded: call    LoadFile\r
+                jc      lp_err\r
+\r
+                mov     segPalette,dx\r
+lp_err:         ret\r
+LoadPaletteFile ENDP\r
+\1a
\ No newline at end of file