-
Notifications
You must be signed in to change notification settings - Fork 1
/
palette.asm
141 lines (123 loc) · 4.66 KB
/
palette.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
;====
; Color palette
;
; The color palette consists of 32 color entries (0-31). Each color is a byte
; containing 2-bit RGB colors in the format (--bbggrr).
;
; Background tiles/patterns can use either the first 16 indices (0-15), or the
; last 16 (16-31). Sprites can only use the last 16 (16-31).
;====
;====
; Dependencies
;====
.ifndef utils.assert
.include "utils/assert.asm"
.endif
.ifndef utils.clobbers
.include "utils/clobbers.asm"
.endif
.ifndef utils.outiBlock
.include "utils/outiBlock.asm"
.endif
.ifndef utils.vdp
.include "utils/vdp.asm"
.endif
;====
; Constants
;====
.define palette.ELEMENT_SIZE_BYTES 1
.define palette.SPRITE_PALETTE 16
.define palette.VRAM_ADDR $c000
;====
; Procedures
;====
;====
; Defines a byte with an approximate RGB value. Each color component is rounded
; to the nearest 85 (0, 85, 170, 255)
;====
.macro "palette.rgb" args red green blue
utils.assert.equals NARGS, 3, "palette.asm \. received the wrong number of arguments"
utils.assert.number red, "palette.asm \.: Invalid red argument"
utils.assert.number green, "palette.asm \.: Invalid green argument"
utils.assert.number blue, "palette.asm \.: Invalid blue argument"
; Round to nearest 85 then AND with $ff to calculate floor
.define \.\@red = (red + 42.5) / 85 & $ff
.define \.\@green = (green + 42.5) / 85 & $ff
.define \.\@blue = (blue + 42.5) / 85 & $ff
; Convert to --bbggrr
.db (\.\@blue * 16) + (\.\@green * 4) + \.\@red
.endm
;====
; Write an approximate RGB value into the current palette index. Each value
; will be rounded to the nearest of: 0, 85, 170, 255
;
; @in red red value
; @in green green value
; @in blue blue value
;
; @in vram the color ram address to write to
; @in c the VDP data port
;====
.macro "palette.writeRgb" args red, green, blue
utils.assert.equals NARGS, 3, "palette.asm \. received the wrong number of arguments"
utils.assert.number red, "palette.asm \.: Invalid red argument"
utils.assert.number green, "palette.asm \.: Invalid green argument"
utils.assert.number blue, "palette.asm \.: Invalid blue argument"
; Round to nearest 85 then AND with $ff to calculate floor
.define \.\@red = (red + 42.5) / 85 & $ff
.define \.\@green = (green + 42.5) / 85 & $ff
.define \.\@blue = (blue + 42.5) / 85 & $ff
; Convert to --bbggrr
utils.clobbers "af"
ld a, (\.\@blue * 16) + (\.\@green * 4) + \.\@red
out (c), a ; write color
utils.clobbers.end
.endm
;====
; Write raw color data into Color RAM
;
; @in address start address of the palette data
; @in size data size in bytes. Due to WLA-DX limitations this must be an immediate
; value, i.e. it can't be calculate from a size calculation like end - start
; It can be a size label (such as using .incbin "file.bin" fsize size)
; so long as this label is defined before this macro is called.
;====
.macro "palette.writeBytes" args address size
utils.assert.equals NARGS, 2, "palette.asm \. received the wrong number of arguments"
utils.assert.label address, "palette.asm \.: Invalid address argument"
utils.assert.number size, "palette.asm \.: Invalid size argument"
utils.clobbers "hl"
ld hl, address
utils.outiBlock.write size
utils.clobbers.end
.endm
;====
; Writes colors into color RAM. Each color should be a byte containing an RGB
; value in the format --bbggrr
;
; @in dataAddr the address of the data to write
; @in count the number of colors to write
; @in [offset=0] how many colors to skip from the start of the data
;====
.macro "palette.writeSlice" args dataAddr count offset
utils.assert.label dataAddr, "palette.asm \.: Invalid label argument"
utils.assert.number count, "palette.asm \.: Invalid count argument"
.ifdef offset
utils.assert.equals NARGS, 3, "palette.asm \. received the wrong number of arguments"
utils.assert.number offset, "palette.asm \.: Expected count to be a numeric value"
utils.outiBlock.writeSlice dataAddr, palette.ELEMENT_SIZE_BYTES, count, offset
.else
utils.assert.equals NARGS, 2, "palette.asm \. received the wrong number of arguments"
utils.outiBlock.writeSlice dataAddr, palette.ELEMENT_SIZE_BYTES, count, 0
.endif
.endm
;====
; Set the current palette index (0-31) ready to write data into
;
; @in index the palette index (0-31)
;====
.macro "palette.setIndex" args index
utils.assert.equals NARGS, 1, "palette.asm \. received the wrong number of arguments"
utils.assert.range index, 0, 31, "palette.asm \.: Invalid index argument"
utils.vdp.prepWrite (palette.VRAM_ADDR + index)
.endm