forked from NEO-SPECTRUMAN/SpecEmu
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPalettes.asm
430 lines (340 loc) · 16.1 KB
/
Palettes.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
.data?
align 4
ChooseColorStruct CHOOSECOLOR <>
CustomColours COLORREF 16 DUP(?) ; 16 custom colours
CustomColoursBak COLORREF 16 DUP(?) ; backup of 16 custom colours in case of user cancel
CustomPaletteFilename BYTE MAX_PATH dup(?)
.data
MAXPALETTES equ 4
PALETTE_SPECTRUM equ 0
PALETTE_GREENSCREEN equ 1
PALETTE_GRAYSCALE equ 2
PALETTE_CUSTOM equ 3
; default custom palette entries for color control
InitCustomPalette db 0,0,0,0,19,33,66,0,111,13,2,0,150,24,124,0
db 37,99,27,0,20,99,99,0,150,143,29,0,218,218,214,0
db 0,0,0,0,52,86,165,0,192,55,10,0,213,32,186,0
db 38,182,35,0,57,198,190,0,213,217,51,0,255,255,255,0
align 4
DDPalettePtrs dd DDPalette_RGB ; standard Spectrum colours
dd DDPalette_AGS ; Amstrad Green-Screen Monitor
dd DDPalette_GS ; grayscale
dd DDPalette_Custom
BR0 equ 70
BR1 equ 80
BR2 equ 90
BR3 equ 100
;b0 equ 0
;b1 equ 1
;b2 equ 2
;b3 equ 8 ; for stripes.szx
b0 equ 0
b1 equ 0
b2 equ 0
b3 equ 0
; standard Spectrum display colours
DDPalette_RGB db b0, b0, b0
db b0, b0, BR0
db BR0, b0, b0
db BR0, b0, BR0
db b0, BR0, b0
db b0, BR0, BR0
db BR0, BR0, b0
db BR0, BR0, BR0
db b1, b1, b1
db b1, b1, BR1
db BR1, b1, b1
db BR1, b1, BR1
db b1, BR1, b1
db b1, BR1, BR0
db BR1, BR1, b1
db BR1, BR1, BR1
db b2, b2, b2
db b2, b2, BR2
db BR2, b2, b2
db BR2, b2, BR2
db b2, BR2, b2
db b2, BR2, BR2
db BR2, BR2, b2
db BR2, BR2, BR2
db b3, b3, b3
db b3, b3, BR3
db BR3, b3, b3
db BR3, b3, BR3
db b3, BR3, b3
db b3, BR3, BR3
db BR3, BR3, b3
db BR3, BR3, BR3
; Amstrad Green-Screen Monitor
DDPalette_AGS db 0, (BR0/8)*0, 0
db 0, (BR0/8)*1, 0
db 0, (BR0/8)*2, 0
db 0, (BR0/8)*3, 0
db 0, (BR0/8)*4, 0
db 0, (BR0/8)*5, 0
db 0, (BR0/8)*6, 0
db 0, (BR0/8)*7, 0
db 0, (BR1/8)*0, 0
db 0, (BR1/8)*1, 0
db 0, (BR1/8)*2, 0
db 0, (BR1/8)*3, 0
db 0, (BR1/8)*4, 0
db 0, (BR1/8)*5, 0
db 0, (BR1/8)*6, 0
db 0, (BR1/8)*7, 0
db 0, (BR2/8)*0, 0
db 0, (BR2/8)*1, 0
db 0, (BR2/8)*2, 0
db 0, (BR2/8)*3, 0
db 0, (BR2/8)*4, 0
db 0, (BR2/8)*5, 0
db 0, (BR2/8)*6, 0
db 0, (BR2/8)*7, 0
db 0, (BR3/8)*0, 0
db 0, (BR3/8)*1, 0
db 0, (BR3/8)*2, 0
db 0, (BR3/8)*3, 0
db 0, (BR3/8)*4, 0
db 0, (BR3/8)*5, 0
db 0, (BR3/8)*6, 0
db 0, (BR3/8)*7, 0
; grayscale
DDPalette_GS db (BR0/8)*0, (BR0/8)*0, (BR0/8)*0
db (BR0/8)*1, (BR0/8)*1, (BR0/8)*1
db (BR0/8)*2, (BR0/8)*2, (BR0/8)*2
db (BR0/8)*3, (BR0/8)*3, (BR0/8)*3
db (BR0/8)*4, (BR0/8)*4, (BR0/8)*4
db (BR0/8)*5, (BR0/8)*5, (BR0/8)*5
db (BR0/8)*6, (BR0/8)*6, (BR0/8)*6
db (BR0/8)*7, (BR0/8)*7, (BR0/8)*7
db (BR1/8)*0, (BR1/8)*0, (BR1/8)*0
db (BR1/8)*1, (BR1/8)*1, (BR1/8)*1
db (BR1/8)*2, (BR1/8)*2, (BR1/8)*2
db (BR1/8)*3, (BR1/8)*3, (BR1/8)*3
db (BR1/8)*4, (BR1/8)*4, (BR1/8)*4
db (BR1/8)*5, (BR1/8)*5, (BR1/8)*5
db (BR1/8)*6, (BR1/8)*6, (BR1/8)*6
db (BR1/8)*7, (BR1/8)*7, (BR1/8)*7
db (BR2/8)*0, (BR2/8)*0, (BR2/8)*0
db (BR2/8)*1, (BR2/8)*1, (BR2/8)*1
db (BR2/8)*2, (BR2/8)*2, (BR2/8)*2
db (BR2/8)*3, (BR2/8)*3, (BR2/8)*3
db (BR2/8)*4, (BR2/8)*4, (BR2/8)*4
db (BR2/8)*5, (BR2/8)*5, (BR2/8)*5
db (BR2/8)*6, (BR2/8)*6, (BR2/8)*6
db (BR2/8)*7, (BR2/8)*7, (BR2/8)*7
db (BR3/8)*0, (BR3/8)*0, (BR3/8)*0
db (BR3/8)*1, (BR3/8)*1, (BR3/8)*1
db (BR3/8)*2, (BR3/8)*2, (BR3/8)*2
db (BR3/8)*3, (BR3/8)*3, (BR3/8)*3
db (BR3/8)*4, (BR3/8)*4, (BR3/8)*4
db (BR3/8)*5, (BR3/8)*5, (BR3/8)*5
db (BR3/8)*6, (BR3/8)*6, (BR3/8)*6
db (BR3/8)*7, (BR3/8)*7, (BR3/8)*7
; custom Spectrum display colours (built from the default palette or "custompalette.pal")
DDPalette_Custom db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
db 0, 0, 0
PaletteFilename db "custompalette.pal", 0
.code
LoadCustomPalettes proc uses esi edi ecx
local PaletteFH
; initialise custom palette filename
invoke GetAppPath, ADDR CustomPaletteFilename
lea edi, CustomPaletteFilename
@@: mov al, [edi]
inc edi
or al, al
jnz @B
dec edi
lea esi, PaletteFilename
mov ecx, sizeof PaletteFilename
rep movsb
; initialise default custom palette
lea esi, InitCustomPalette
lea edi, CustomColours
mov ecx, sizeof CustomColours
rep movsb
invoke filesize, ADDR CustomPaletteFilename
.if eax == sizeof CustomColours ; sizeof CustomPalette file
invoke CreateFile, ADDR CustomPaletteFilename,
GENERIC_READ,
FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
mov PaletteFH, eax
.if PaletteFH != INVALID_HANDLE_VALUE
invoke ReadFile, PaletteFH,
ADDR CustomColours, sizeof CustomColours,
ADDR BytesMoved, NULL
invoke CloseHandle, PaletteFH
.endif
.endif
invoke SetCustomPalette ; set our new custom palette
ret
LoadCustomPalettes endp
SaveCustomPalettes proc
local PaletteFH
invoke CreateFile, ADDR CustomPaletteFilename,
GENERIC_WRITE,
FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
mov PaletteFH, eax
.if PaletteFH != INVALID_HANDLE_VALUE
invoke WriteFile, PaletteFH,
ADDR CustomColours, sizeof CustomColours,
ADDR BytesSaved, NULL
invoke CloseHandle, PaletteFH
.endif
ret
SaveCustomPalettes endp
SetSpectrumPalette proc uses esi edi ebx,
PalNum: DWORD
local SpecCol:DWORD
mov eax, PalNum
mov UserPalette, eax
mov esi, [DDPalettePtrs+eax*4] ; esi points to selected palette entries
lea edi, ddSurfacePalette+(CLR_SPECBASE*4)
SETLOOP 32 ; 32 Spectrum display colours
mov eax, [RedComponent]
movzx bx, byte ptr [esi] ; red percentage
inc esi
invoke GetPercentComponent, eax, bx
and eax, [RedComponent]
mov [SpecCol], eax
mov eax, [GreenComponent]
movzx bx, byte ptr [esi] ; green percentage
inc esi
invoke GetPercentComponent, eax, bx
and eax, [GreenComponent]
or [SpecCol], eax
mov eax, [BlueComponent]
movzx bx, byte ptr [esi] ; blue percentage
inc esi
invoke GetPercentComponent, eax, bx
and eax, [BlueComponent]
or eax, [SpecCol]
stosd
ENDLOOP
ret
SetSpectrumPalette endp
EditCustomPalette proc uses esi edi ecx
ASSUME ESI: PTR CHOOSECOLOR
lea esi, ChooseColorStruct
mov [esi].lStructSize, sizeof CHOOSECOLOR
m2m [esi].hwndOwner, hWnd
mov [esi].hInstance, NULL
mov [esi].rgbResult, 0 ; to do!
mov [esi].lpCustColors, OFFSET CustomColours
mov [esi].Flags, CC_FULLOPEN
ASSUME ESI: NOTHING
; backup custom colours
lea esi, CustomColours
lea edi, CustomColoursBak
mov ecx, sizeof CustomColours
rep movsb
invoke ChooseColor, ADDR ChooseColorStruct
.if eax != NULL
; if OK then create and enable the new custom palette
invoke SetCustomPalette ; set our new custom palette
invoke SetSpectrumPalette, PALETTE_CUSTOM
invoke SetDirtyLines
UPDATEWINDOW
.else
; else restore the old custom colours
lea esi, CustomColoursBak
lea edi, CustomColours
mov ecx, sizeof CustomColours
rep movsb
.endif
ret
EditCustomPalette endp
SetCustomPalette proc uses esi edi ebx ecx
lea esi, CustomColours
lea edi, DDPalette_Custom ; address BRIGHT 0 (and half-brighter) table
SETLOOP 2
SETLOOP 8
; get Red component
invoke GetColourAsPercent, byte ptr [esi] ; R (0-255)
inc esi
mov [edi], al ; store R percent
mov [edi+24], al ; and into the half-brighter table
inc edi
; get Green component
invoke GetColourAsPercent, byte ptr [esi] ; G (0-255)
inc esi
mov [edi], al ; store G percent
mov [edi+24], al ; and into the half-brighter table
inc edi
; get Blue component
invoke GetColourAsPercent, byte ptr [esi] ; B (0-255)
inc esi
mov [edi], al ; store B percent
mov [edi+24], al ; and into the half-brighter table
inc edi
inc esi ; skip to the next COLORREF entry
ENDLOOP
add edi, 24 ; advance to address BRIGHT 1 (and half-brighter) table
ENDLOOP
ret
SetCustomPalette endp
; given a colour value (0-255), return that as a percentage of the range (100% being 255)
; (Colour / 255) × 100, or...
; (Colour * 100) / 255
GetColourAsPercent proc Colour: BYTE
; movzx eax, Colour
; invoke MulDiv, eax, 100, 255
; ret
movzx eax, Colour
mov cx, 100
mul cx
invoke IntDiv, eax, 255
ret
GetColourAsPercent endp
GetPercentComponent proc uses ebx ecx,
Colour: DWORD,
Percent:WORD
mov eax, Colour
.if eax != 0
xor cl, cl ; initialise our bit shift counter
; count the number of shifts required until our colour bits sit in the lowest bits
.while TRUE
test eax, 1
.break .if !ZERO?
inc cl
shr eax, 1
.endw
movzx ebx, Percent
invoke GetPercent, eax, ebx ; eax = our new colour intensity percentage
shl eax, cl ; shift our colour bits back into position
.endif
ret
GetPercentComponent endp