From http://www.jwz.org/xscreensaver/xscreensaver-5.38.tar.gz
[xscreensaver] / hacks / images / m6502 / texture.asm
1 ; -*- mode: c; tab-width: 4; fill-column: 128 -*-
2 ; vi: set ts=4 tw=128:
3
4 ; Texture, Copyright (c) 2017 Dave Odell <dmo2118@gmail.com>
5 ;
6 ; Permission to use, copy, modify, distribute, and sell this software and its
7 ; documentation for any purpose is hereby granted without fee, provided that
8 ; the above copyright notice appear in all copies and that both that
9 ; copyright notice and this permission notice appear in supporting
10 ; documentation.  No representations are made about the suitability of this
11 ; software for any purpose.  It is provided "as is" without express or 
12 ; implied warranty.
13
14 ; A port of 20 year old QBasic code to a much more modern platform.
15
16
17
18
19
20         lda $fe
21         sta src_row
22
23         ldy #0
24 top_loop:
25         lda $fe
26         and #$f
27         sbc #$8
28         adc src_row,y
29         iny
30         sta src_row,y
31         cpy #31
32         bne top_loop
33
34 lda #$00
35 sta $0
36 lda #$02
37 sta $1
38
39 init_loop:
40         jsr tex
41         clc
42         lda $0
43         adc #$20
44         sta $0
45         lda $1
46         adc #0
47         sta $1
48         cmp #$06
49         bne init_loop
50
51 lda #$e0
52 sta $0
53 lda #$05
54 sta $1
55
56 loop:
57         ;jmp skip_blit
58
59         clc
60         lda #0
61         blit_loop2:
62                 tay
63                 lda $0220,y
64                 sta $0200,y
65                 lda $0221,y
66                 sta $0201,y
67                 lda $0222,y
68                 sta $0202,y
69                 lda $0223,y
70                 sta $0203,y
71                 lda $0224,y
72                 sta $0204,y
73                 lda $0225,y
74                 sta $0205,y
75                 lda $0226,y
76                 sta $0206,y
77                 lda $0227,y
78                 sta $0207,y
79
80                 tya
81                 adc #8
82         bne blit_loop2
83
84         clc
85         lda #0
86         blit_loop3:
87                 tay
88                 lda $0320,y
89                 sta $0300,y
90                 lda $0321,y
91                 sta $0301,y
92                 lda $0322,y
93                 sta $0302,y
94                 lda $0323,y
95                 sta $0303,y
96                 lda $0324,y
97                 sta $0304,y
98                 lda $0325,y
99                 sta $0305,y
100                 lda $0326,y
101                 sta $0306,y
102                 lda $0327,y
103                 sta $0307,y
104
105                 tya
106                 adc #8
107         bne blit_loop3
108
109         clc
110         lda #0
111         blit_loop4:
112                 tay
113                 lda $0420,y
114                 sta $0400,y
115                 lda $0421,y
116                 sta $0401,y
117                 lda $0422,y
118                 sta $0402,y
119                 lda $0423,y
120                 sta $0403,y
121                 lda $0424,y
122                 sta $0404,y
123                 lda $0425,y
124                 sta $0405,y
125                 lda $0426,y
126                 sta $0406,y
127                 lda $0427,y
128                 sta $0407,y
129
130                 tya
131                 adc #8
132         bne blit_loop4
133
134         lda #0
135         blit_loop5:
136                 tay
137                 lda $0520,y
138                 sta $0500,y
139                 lda $0521,y
140                 sta $0501,y
141                 lda $0522,y
142                 sta $0502,y
143                 lda $0523,y
144                 sta $0503,y
145                 lda $0524,y
146                 sta $0504,y
147                 lda $0525,y
148                 sta $0505,y
149                 lda $0526,y
150                 sta $0506,y
151                 lda $0527,y
152                 sta $0507,y
153
154                 tya
155                 clc
156                 adc #8
157                 cmp #$e0
158         bne blit_loop5
159
160         skip_blit:
161
162         jsr tex
163 jmp loop
164
165 tex:
166         lda $fe
167         and #$f
168         sbc #$8
169         adc src_row
170         sta src_row
171
172         ldy #0
173         tax
174         lda pal0,x
175         sta ($0),y
176         tex_loop0:
177                 lda $fe
178                 and #$f
179                 sbc #$8
180                 ;clc
181                 adc src_row,y
182                 iny
183                 ;clc
184                 adc src_row,y
185                 ror
186                 sta src_row,y
187
188                 tax
189                 lda pal0,x
190                 sta ($0),y
191
192                 cpy #31
193         bne tex_loop0
194         rts
195
196 pal0:
197         dcb $00, $00, $00, $00, $00, $00, $00, $00
198         dcb $00, $00, $0b, $0b, $0b, $0b, $0b, $0b
199         dcb $0b, $0b, $0b, $0b, $0b, $0b, $0b, $0b
200         dcb $0c, $0c, $0c, $0c, $0c, $0c, $0c, $0c
201         dcb $0c, $0c, $0c, $0c, $0c, $0c, $0c, $0c
202         dcb $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
203         dcb $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
204         dcb $0f, $01, $01, $01, $01, $01, $01, $01
205         dcb $01, $01, $01, $01, $01, $01, $01, $01
206         dcb $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
207         dcb $0f, $0f, $0f, $0f, $0f, $0f, $0f, $0f
208         dcb $0f, $0c, $0c, $0c, $0c, $0c, $0c, $0c
209         dcb $0c, $0c, $0c, $0c, $0c, $0c, $0c, $0c
210         dcb $0c, $0b, $0b, $0b, $0b, $0b, $0b, $0b
211         dcb $0b, $0b, $0b, $0b, $0b, $0b, $0b, $00
212         dcb $00, $00, $00, $00, $00, $00, $00, $00
213         dcb $00, $00, $00, $00, $00, $00, $00, $00
214         dcb $00, $00, $00, $00, $00, $00, $00, $00
215         dcb $0b, $0b, $0b, $0b, $0b, $0b, $0b, $0b
216         dcb $0b, $0b, $0b, $0b, $0b, $0b, $0b, $0b
217         dcb $0b, $0b, $0b, $0b, $0b, $0b, $05, $05
218         dcb $05, $05, $05, $05, $05, $05, $05, $05
219         dcb $05, $05, $05, $05, $05, $05, $05, $05
220         dcb $0d, $0d, $0d, $0d, $0d, $0d, $0d, $0d
221         dcb $0d, $0d, $0d, $0d, $0d, $0d, $0d, $0d
222         dcb $0d, $05, $05, $05, $05, $05, $05, $05
223         dcb $05, $05, $05, $05, $05, $05, $05, $05
224         dcb $05, $05, $05, $0b, $0b, $0b, $0b, $0b
225         dcb $0b, $0b, $0b, $0b, $0b, $0b, $0b, $0b
226         dcb $0b, $0b, $0b, $0b, $0b, $0b, $0b, $0b
227         dcb $0b, $00, $00, $00, $00, $00, $00, $00
228         dcb $00, $00, $00, $00, $00, $00, $00, $00
229
230 src_row:
231         ; (32 bytes)
232
233 ; A full-resolution version of the same thing. Not perhaps the most interesting thing to look at.
234
235 ;#include "screenhack.h"
236 ;
237 ;#include <inttypes.h>
238 ;
239 ;struct texture
240 ;{
241 ;       unsigned width, height;
242 ;       Colormap colormap;
243 ;       GC gc;
244 ;       unsigned long palette[128];
245 ;       XImage *image;
246 ;       uint8_t *row;
247 ;       unsigned graininess;
248 ;       unsigned lines;
249 ;};
250 ;
251 ;#define GRAIN(self) (NRAND((self)->graininess * 2 + 1) - (self)->graininess)
252 ;
253 ;static void _put_line(struct texture *self, Display *dpy, Window window, unsigned y)
254 ;{
255 ;       unsigned x;
256 ;       for(x = 0; x != self->width; ++x)
257 ;       {
258 ;               unsigned c1 = self->row[x];
259 ;               unsigned c0 = c1;
260 ;               if(c0 & 64)
261 ;                       c0 ^= 127;
262 ;               XPutPixel(self->image, x, 0, self->palette[(c0 & 63) | ((c1 & 0x80) >> 1)]);
263 ;       }
264 ;
265 ;       XPutImage(dpy, window, self->gc, self->image, 0, 0, 0, y, self->width, 1);
266 ;
267 ;       *self->row += GRAIN(self);
268 ;
269 ;       for(x = 1; x != self->width; ++x);
270 ;       {
271 ;               unsigned avg = self->row[x - 1] + self->row[x];
272 ;               self->row[x] = ((avg + ((avg & 2) >> 1)) >> 1) + GRAIN(self);
273 ;       }
274 ;
275 ;
276 ;}
277 ;
278 ;static void texture_reshape(Display *dpy, Window window, void *self_raw, unsigned w, unsigned h)
279 ;{
280 ;       struct texture *self = self_raw;
281 ;       unsigned x, y;
282 ;
283 ;       if(w == self->width && h == self->height)
284 ;               return;
285 ;
286 ;       self->image->bytes_per_line = 0;
287 ;       self->image->width = w;
288 ;       XInitImage(self->image);
289 ;
290 ;       free(self->row);
291 ;       self->row = malloc(w);
292 ;       free(self->image->data);
293 ;       self->image->data = malloc(w * self->image->bytes_per_line);
294 ;
295 ;       self->width = w;
296 ;       self->height = h;
297 ;
298 ;       *self->row = NRAND(0xff);
299 ;       for(x = 1; x != self->width; ++x)
300 ;               self->row[x] = self->row[x - 1] + GRAIN(self);
301 ;
302 ;       for(y = 0; y != self->height; ++y)
303 ;               _put_line(self, dpy, window, y);
304 ;}
305 ;
306 ;static void *texture_init(Display *dpy, Window window)
307 ;{
308 ;       static const XGCValues gcv_src = {GXcopy};
309 ;       XGCValues gcv = gcv_src;
310 ;       struct texture *self = malloc(sizeof(*self));
311 ;       XWindowAttributes xwa;
312 ;       unsigned i;
313 ;
314 ;       XGetWindowAttributes(dpy, window, &xwa);
315 ;       self->width = 0;
316 ;       self->height = 0;
317 ;       self->colormap = xwa.colormap;
318 ;
319 ;       self->graininess = get_integer_resource(dpy, "graininess", "Graininess");
320 ;       self->lines = get_integer_resource(dpy, "speed", "Speed");
321 ;
322 ;       for(i = 0; i != 64; ++i)
323 ;       {
324 ;               XColor color;
325 ;               unsigned short a = i * (0x10000 / 64);
326 ;
327 ;               color.red   = a;
328 ;               color.green = a;
329 ;               color.blue  = a;
330 ;               if(!XAllocColor(dpy, xwa.colormap, &color))
331 ;                       abort();
332 ;               self->palette[i] = color.pixel;
333 ;
334 ;               color.red   = 0;
335 ;               color.green = a;
336 ;               color.blue  = 0;
337 ;               if(!XAllocColor(dpy, xwa.colormap, &color))
338 ;                       abort();
339 ;               self->palette[i | 64] = color.pixel;
340 ;       }
341 ;
342 ;       self->gc = XCreateGC(dpy, window, GCFunction, &gcv);
343 ;       self->image = XCreateImage(dpy, xwa.visual, xwa.depth, ZPixmap, 0, NULL, 0, 1, 32, 0);
344 ;       self->row = NULL;
345 ;
346 ;       texture_reshape(dpy, window, self, xwa.width, xwa.height);
347 ;
348 ;       return self;
349 ;}
350 ;
351 ;static unsigned long texture_draw(Display *dpy, Window window, void *self_raw)
352 ;{
353 ;       struct texture *self = self_raw;
354 ;       unsigned y;
355 ;       XCopyArea(dpy, window, window, self->gc, 0, self->lines, self->width, self->height - self->lines, 0, 0);
356 ;       for(y = 0; y != self->lines; ++y)
357 ;               _put_line(self, dpy, window, self->height - self->lines + y);
358 ;       return 16667;
359 ;}
360 ;
361 ;static Bool texture_event (Display *dpy, Window window, void *self_raw, XEvent *event)
362 ;{
363 ;       return False;
364 ;}
365 ;
366 ;static void texture_free(Display *dpy, Window window, void *self_raw)
367 ;{
368 ;       struct texture *self = self_raw;
369 ;
370 ;       XFreeGC(dpy, self->gc);
371 ;       XFreeColors(dpy, self->colormap, self->palette, 128, 0);
372 ;       XDestroyImage(self->image);
373 ;       free(self->row);
374 ;       free(self);
375 ;}
376 ;
377 ;static const char *texture_defaults[] =
378 ;{
379 ;       "*speed:      2",
380 ;       "*graininess: 1",
381 ;       "*fpsSolid:   True",
382 ;       "*fpsTop:     True",
383 ;       0
384 ;};
385 ;
386 ;static XrmOptionDescRec texture_options[] =
387 ;{
388 ;       {"-speed",      ".speed",      XrmoptionSepArg, 0},
389 ;       {"-graininess", ".graininess", XrmoptionSepArg, 0},
390 ;       {0, 0, 0, 0}
391 ;};
392 ;
393 ;XSCREENSAVER_MODULE("Texture", texture)