comparison clojure/com/aurellem/run/image.clj @ 512:7ba07a6adb0c

going to correct premium stupdity.
author Robert McIntyre <rlm@mit.edu>
date Fri, 22 Jun 2012 18:38:22 -0500
parents 964957680c11
children 3dbb863eb801
comparison
equal deleted inserted replaced
511:964957680c11 512:7ba07a6adb0c
28 ;; 2. split into a grid of 8x8 pixels 28 ;; 2. split into a grid of 8x8 pixels
29 ;; 3. convert all RGB colors to gb-RGB colors 29 ;; 3. convert all RGB colors to gb-RGB colors
30 ;; 4. determine efficient color palletes for the image 30 ;; 4. determine efficient color palletes for the image
31 ;; 5. output efficient assembly code to draw the image to the gb 31 ;; 5. output efficient assembly code to draw the image to the gb
32 ;; screen. 32 ;; screen.
33
34
35
36
37
38
39
40
41
42
43
44 33
45 34
46 (def image-program-target 0xB000) 35 (def image-program-target 0xB000)
47 36
48 (def display-width 160) 37 (def display-width 160)
331 accepted 320 accepted
332 (conj accepted new-element))) 321 (conj accepted new-element)))
333 [] 322 []
334 (sort-by (comp - count) objs))) 323 (sort-by (comp - count) objs)))
335 324
336 (defn absorb-combine-4 [objs]
337
338 )
339
340 (defn palettes [^BufferedImage image] 325 (defn palettes [^BufferedImage image]
341 (let [palettes (map tile->palette (gb-tiles image)) 326 (let [palettes (map tile->palette (gb-tiles image))
342 unique-palettes (absorb-contract (set palettes))] 327 unique-palettes (absorb-contract (set palettes))]
343 unique-palettes)) 328 unique-palettes))
344 329
391 (let [tile-colors (set (tile->palette tile))] 376 (let [tile-colors (set (tile->palette tile))]
392 [(tile-index tile) 377 [(tile-index tile)
393 (palette-index 378 (palette-index
394 (tile-pallete tile image-palettes))])))})) 379 (tile-pallete tile image-palettes))])))}))
395 380
396
397
398 (defn wait-until-v-blank 381 (defn wait-until-v-blank
399 "Modified version of frame-metronome. waits untill LY == 144, 382 "Modified version of frame-metronome. waits untill LY == 144,
400 indicating start of v-blank period." 383 indicating start of v-blank period."
401 [] 384 []
402 (let [timing-loop 385 (let [timing-loop
409 144 ;; compare LY (in A) with 144 392 144 ;; compare LY (in A) with 144
410 0x20 ;; jump back to beginning if LY != 144 (not-v-blank) 393 0x20 ;; jump back to beginning if LY != 144 (not-v-blank)
411 (->signed-8-bit 394 (->signed-8-bit
412 (+ -4 (- (count timing-loop))))]] 395 (+ -4 (- (count timing-loop))))]]
413 (concat timing-loop continue-if-144))) 396 (concat timing-loop continue-if-144)))
414
415 397
416 (def bg-character-data 0x9000) 398 (def bg-character-data 0x9000)
417 399
418 (defn gb-tile->bytes 400 (defn gb-tile->bytes
419 "Tile is a vector of 64 numbers between 0 and 3 that 401 "Tile is a vector of 64 numbers between 0 and 3 that
440 (vec 422 (vec
441 (flatten 423 (flatten
442 (map row->bits 424 (map row->bits
443 (partition 8 tile)))))) 425 (partition 8 tile))))))
444 426
445
446 (defn write-data 427 (defn write-data
447 "Efficient assembly to write a sequence of values to 428 "Efficient assembly to write a sequence of values to
448 memory, starting at a target address." 429 memory, starting at a target address."
449 [base-address target-address data] 430 [base-address target-address data]
450 (let [len (count data) 431 (let [len (count data)
451 program-length 21] ;; change this if program length 432 program-length 21] ;; change this if program length
452 ;; below changes! 433 ;; below changes!
453
454 (flatten 434 (flatten
455 [0x21 ;; load data address start into HL 435 [0x21 ;; load data address start into HL
456 (reverse (disect-bytes-2 (+ base-address program-length))) 436 (reverse (disect-bytes-2 (+ base-address program-length)))
457 437
458 0x01 ;; load target address into BC 438 0x01 ;; load target address into BC
480 (reverse 460 (reverse
481 (disect-bytes-2 461 (disect-bytes-2
482 (+ len base-address program-length))) 462 (+ len base-address program-length)))
483 data]))) 463 data])))
484 464
465 (defn write-image
466 "Assume the image data is 160x144 pixels specified as 360 blocks."
467 [base-address target-address image-data]
468
469 (let [len (count image-data)
470 gen-program
471 (fn [program-length]
472 (flatten
473 [0x21 ;; load data address start into HL
474 (reverse
475 (disect-bytes-2 (+ base-address program-length)))
476
477 0x01 ;; load target address into BC
478 (reverse (disect-bytes-2 target-address))
479
480 0x1E ;; total-rows (18) -> E
481 1
482
483 0x16 ;; total columns (20) -> D
484 20
485
486 ;; wite one block (8x8 pixels) to screen.
487 0x3E
488 16 ;; load 16 into A
489
490 0xF5 ;; push A
491
492 ;; data x-fer loop start
493 0x2A ;; (HL) -> A; HL++;
494 0x02 ;; A -> (BC);
495 0x03 ;; INC BC;
496
497
498 0xF1 ;; pop A
499
500 0x3D ;; dec A
501 0x20 ;;
502 (->signed-8-bit -8) ;; continue writing block
503
504 0x15 ;; dec D
505 0x20
506 (->signed-8-bit -13) ;; continue writing row
507
508 ;; row is complete, advance to next row
509 ;; HL += 192
510
511 0xC5 ;; push BC
512
513 0x06 ;; 0 -> B
514 0
515
516 0x0E
517 0 ;; 192 -> C
518
519 0x09 ;; HL + BC -> HL
520
521 0xC1 ;; pop BC
522
523 0x1D ;; dec E
524 0x20
525 (->signed-8-bit -23) ;; contunue writing picture
526
527 0xC3
528 (reverse
529 (disect-bytes-2
530 (+ len base-address program-length)))]))]
531 (flatten (concat
532 (gen-program (count (gen-program 0)))
533 image-data))))
485 534
486 (defn test-write-data [] 535 (defn test-write-data []
487 (let [test-data (concat (range 256) 536 (let [test-data (concat (range 256)
488 (reverse (range 256))) 537 (reverse (range 256)))
489 base-address 0xC000 538 base-address 0xC000
522 571
523 (defn select-LCD-bank [n] 572 (defn select-LCD-bank [n]
524 (assert (or (= n 0) (= n 1))) 573 (assert (or (= n 0) (= n 1)))
525 (write-byte LCD-bank-select-address n)) 574 (write-byte LCD-bank-select-address n))
526 575
576 (defn write-image* [_ _ _] [])
577
527 (defn display-image-kernel [base-address ^BufferedImage image] 578 (defn display-image-kernel [base-address ^BufferedImage image]
528 (let [gb-image (image->gb-image image) 579 (let [gb-image (image->gb-image image)
529 580
530 A [(clear-music-registers) 581 A [(clear-music-registers)
531 582
532 ;; [X] disable LCD protection circuit. 583 ;; [X] disable LCD protection circuit.
533 (write-byte LCD-control-register 0x00) 584 (write-byte LCD-control-register 0x00)
534 ;; now we can write to all video RAM anytime with 585 ;; now we can write to all video RAM anytime with
535 ;; impunity. 586 ;; impunity.
536 587
537 ;; we're only using background palettes; just set the 588 ;; [ ] We're only using background palettes; just set the
538 ;; minimum required bg palettes for this image, 589 ;; minimum required bg palettes for this image, starting
539 ;; starting with palette #0. 590 ;; with palette #0.
540 591
541 (set-palettes bg-palette-select bg-palette-data 592 (set-palettes bg-palette-select bg-palette-data
542 (:palettes gb-image)) 593 (:palettes gb-image))
543 594
544 ;; [X] switch to bank 0 to set BG character data. 595 ;; [X] switch to bank 0 to set BG character data.
545 (select-LCD-bank 0) 596 (select-LCD-bank 0)
546
547 ;; [X] set SCX and SCY to 0 597 ;; [X] set SCX and SCY to 0
548 (write-byte SCX-register 0) 598 (write-byte SCX-register 0)
549 (write-byte SCY-register 0) 599 (write-byte SCY-register 0)
550
551 ] 600 ]
552 A (flatten A) 601 A (flatten A)
553 602
554 B [;; [X] write minimum amount of tiles to BG character 603 B [;; [X] write minimum amount of tiles to BG character
555 ;; section 604 ;; section
560 (map gb-tile->bytes (:tiles gb-image))))] 609 (map gb-tile->bytes (:tiles gb-image))))]
561 B (flatten B) 610 B (flatten B)
562 611
563 612
564 C [;; [ ] write image to the screen in terms of tiles 613 C [;; [ ] write image to the screen in terms of tiles
565 (write-data 614 (write-image
566 (+ base-address (+ (count A) (count B))) 615 (+ base-address (+ (count A) (count B)))
567 BG-1-address 616 BG-1-address
568 (map first (:data gb-image)))] 617 (map first (:data gb-image)))]
569 618
570 C (flatten C) 619 C (flatten C)
571 620
572 D [;; [ ] specifiy pallets for each character 621 D [;; [ ] specifiy pallets for each character
573 (select-LCD-bank 1) 622 (select-LCD-bank 1)
574 (write-data 623 (write-image
575 (+ base-address (+ (count A) (count B) (count C))) 624 (+ base-address (+ (count A) (count B) (count C)))
576 BG-1-address 625 BG-1-address
577 (map second (:data gb-image))) 626 (map second (:data gb-image)))
578 627
579 628
593 "0" ;; BG-1 or BG-2 ? 642 "0" ;; BG-1 or BG-2 ?
594 "0" ;; OBJ-block composition 643 "0" ;; OBJ-block composition
595 "0" ;; OBJ-on flag 644 "0" ;; OBJ-on flag
596 "1") ;; no-effect 645 "1") ;; no-effect
597 2)) 646 2))
598
599 647
600 (infinite-loop)] 648 (infinite-loop)]
601 D (flatten D)] 649 D (flatten D)]
602 650
603 (concat A B C D))) 651 (concat A B C D)))
604
605 652
606 (defn display-image [#^BufferedImage image] 653 (defn display-image [#^BufferedImage image]
607 (let [kernel-address 0xB000] 654 (let [kernel-address 0xB000]
608 (-> (tick (tick (tick (mid-game)))) 655 (-> (tick (tick (tick (mid-game))))
609 (set-memory-range 656 (set-memory-range
610 kernel-address 657 kernel-address
611 (display-image-kernel kernel-address image)) 658 (display-image-kernel kernel-address image))
612 (PC! kernel-address)))) 659 (PC! kernel-address))))
613
614
615