comparison clojure/com/aurellem/run/image.clj @ 511:964957680c11

got an image to display, but it doesn't tile correctly.
author Robert McIntyre <rlm@mit.edu>
date Fri, 22 Jun 2012 15:03:41 -0500
parents b9814e3114e4
children 7ba07a6adb0c
comparison
equal deleted inserted replaced
510:b9814e3114e4 511:964957680c11
88 (def obj-palette-select 0xFF6A) 88 (def obj-palette-select 0xFF6A)
89 (def obj-palette-data 0xFF6B) 89 (def obj-palette-data 0xFF6B)
90 90
91 (def max-palettes 8) 91 (def max-palettes 8)
92 92
93 (defn write-data [target data] 93 (defn write-byte [target data]
94 (flatten 94 (flatten
95 [0x3E ;; load literal to A 95 [0x3E ;; load literal to A
96 data 96 data
97 0xEA ;; load A into target 97 0xEA ;; load A into target
98 (reverse (disect-bytes-2 target))])) 98 (reverse (disect-bytes-2 target))]))
112 (Integer/parseInt 112 (Integer/parseInt
113 (Integer/toBinaryString palette-num) 10)) 113 (Integer/toBinaryString palette-num) 10))
114 "00" ;; color num 114 "00" ;; color num
115 "0" ;; H/L 115 "0" ;; H/L
116 ) 2)] 116 ) 2)]
117 (write-data palette-select-address palette-write-data))) 117 (write-byte palette-select-address palette-write-data)))
118 118
119 (defn set-palettes [palette-select palette-data palettes] 119 (defn set-palettes [palette-select palette-data palettes]
120 (assert (<= (count palettes)) max-palettes) 120 (assert (<= (count palettes)) max-palettes)
121 (flatten 121 (flatten
122 [(begin-sequential-palette-write 0 palette-select) 122 [(begin-sequential-palette-write 0 palette-select)
123 (map (partial write-data palette-data) 123
124 (flatten (map gb-rgb->bits palettes)))])) 124 0x21 ;; target address to HL
125 (reverse (disect-bytes-2 palette-data))
126
127
128 (for [palette palettes]
129 (map (fn [byte]
130 [0x3E ;; literal to A
131 byte
132 0x77]) ;; A -> (HL)
133
134 (flatten
135 (map #(gb-rgb->bits (get palette % [0 0 0]))
136 (range 4)))))]))
137
125 138
126 (defn display-one-color 139 (defn display-one-color
127 "Displayes a single color onto the gameboy screen. Input rgb in 140 "Displayes a single color onto the gameboy screen. Input rgb in
128 gameboy rgb." 141 gameboy rgb."
129 ([state [r g b]] 142 ([state [r g b]]
130 ;; construct a kernel that displays a single color 143 ;; construct a kernel that displays a single color
131 (let 144 (let
132 [palettes (repeat 8 [r g b]) 145 [palettes (repeat 8 [[r g b] [r g b] [r g b] [r g b]])
133 kernel-address 0xC000 146 kernel-address 0xC000
134 kernel 147 kernel
135 [0xF3 ;; disable interrupts 148 [0xF3 ;; disable interrupts
136 (clear-music-registers) 149 (clear-music-registers)
137 (frame-metronome) 150 (frame-metronome)
138 (set-palettes obj-palette-select obj-palette-data palettes) 151 ;;(set-palettes
139 (set-palettes bg-palette-select bg-palette-data palettes) 152 ;; obj-palette-select obj-palette-data palettes)
153 (set-palettes
154 bg-palette-select bg-palette-data palettes)
140 (infinite-loop)]] 155 (infinite-loop)]]
141 (-> (set-memory-range state 156 (-> (set-memory-range state
142 kernel-address (flatten kernel)) 157 kernel-address (flatten kernel))
143 (PC! kernel-address)))) 158 (PC! kernel-address))))
144 ([[r g b]] 159 ([[r g b]]
491 vec 506 vec
492 (subvec target-address 507 (subvec target-address
493 (+ target-address 508 (+ target-address
494 (count test-data)))))))) 509 (count test-data))))))))
495 510
511 (def LCD-bank-select-address 0xFF4F)
512
513 (def BG-1-address 0x9800)
514 (def BG-2-address 0x9C00)
515 (def character-data-address 0x8000)
516
517 (def LCD-control-register 0xFF40)
518 (def STAT-register 0xFF41)
519
520 (def SCX-register 0xFF42)
521 (def SCY-register 0xFF43)
522
523 (defn select-LCD-bank [n]
524 (assert (or (= n 0) (= n 1)))
525 (write-byte LCD-bank-select-address n))
526
496 (defn display-image-kernel [base-address ^BufferedImage image] 527 (defn display-image-kernel [base-address ^BufferedImage image]
497 (let [gb-image (image->gb-image image)] 528 (let [gb-image (image->gb-image image)
498 529
499 [(clear-music-registers) 530 A [(clear-music-registers)
500 531
501 ;; [ ] disable LCD protection circuit. 532 ;; [X] disable LCD protection circuit.
502 533 (write-byte LCD-control-register 0x00)
503 ;; now we can write to all video RAM anytime with 534 ;; now we can write to all video RAM anytime with
504 ;; impunity. 535 ;; impunity.
505 536
506 537 ;; we're only using background palettes; just set the
507 538 ;; minimum required bg palettes for this image,
508 ;; we're only using background palettes; just set the 539 ;; starting with palette #0.
509 ;; minimum required bg palettes for this image, 540
510 ;; starting with palette #0. 541 (set-palettes bg-palette-select bg-palette-data
511 542 (:palettes gb-image))
512 (set-palettes bg-palette-select bg-palette-data 543
513 (:palettes gb-image)) 544 ;; [X] switch to bank 0 to set BG character data.
514 545 (select-LCD-bank 0)
515 ;; [ ] switch to bank 0 to set BG character data. 546
516 547 ;; [X] set SCX and SCY to 0
517 548 (write-byte SCX-register 0)
518 ;; [ ] write minimum amount of tiles to BG character 549 (write-byte SCY-register 0)
519 ;; section 550
520 551 ]
521 552 A (flatten A)
522 ;; [ ] disable the display of OBJ tiles. 553
523 554 B [;; [X] write minimum amount of tiles to BG character
524 555 ;; section
525 ;; [ ] reactivate the LCD display 556 (write-data
526 557 (+ base-address (count A))
527 558 character-data-address
528 (infinite-loop)] 559 (flatten
529 560 (map gb-tile->bytes (:tiles gb-image))))]
530 561 B (flatten B)
531 )) 562
532 563
533 564 C [;; [ ] write image to the screen in terms of tiles
534 565 (write-data
566 (+ base-address (+ (count A) (count B)))
567 BG-1-address
568 (map first (:data gb-image)))]
569
570 C (flatten C)
571
572 D [;; [ ] specifiy pallets for each character
573 (select-LCD-bank 1)
574 (write-data
575 (+ base-address (+ (count A) (count B) (count C)))
576 BG-1-address
577 (map second (:data gb-image)))
578
579
580 ;; [X] reactivate the LCD display
581 ;; we're using only BG images, located at
582 ;; BG-1 (0x9800), with background character data
583 ;; stored starting at 0x8000
584
585 (write-byte
586 LCD-control-register
587 (Integer/parseInt
588 (str
589 "1" ;; LCDC on/off
590 "0" ;; Window code area
591 "0" ;; Windowing on?
592 "1" ;; BG tile base (1 = 0x8000)
593 "0" ;; BG-1 or BG-2 ?
594 "0" ;; OBJ-block composition
595 "0" ;; OBJ-on flag
596 "1") ;; no-effect
597 2))
598
599
600 (infinite-loop)]
601 D (flatten D)]
602
603 (concat A B C D)))
604
605
606 (defn display-image [#^BufferedImage image]
607 (let [kernel-address 0xB000]
608 (-> (tick (tick (tick (mid-game))))
609 (set-memory-range
610 kernel-address
611 (display-image-kernel kernel-address image))
612 (PC! kernel-address))))
613
614
615