2015-03-25 16:20:06 +01:00
|
|
|
type pixel = {
|
|
|
|
r : char;
|
|
|
|
g : char;
|
|
|
|
b : char;
|
|
|
|
a : char;
|
|
|
|
}
|
|
|
|
|
|
|
|
type t = {
|
|
|
|
width : int;
|
|
|
|
height : int;
|
|
|
|
data : pixel array;
|
|
|
|
}
|
|
|
|
|
2015-04-08 14:49:24 +02:00
|
|
|
type control = {
|
|
|
|
lcd_display_enable : bool;
|
|
|
|
tile_map_select : int;
|
|
|
|
window_display_enable : bool;
|
|
|
|
tile_data_select : int;
|
|
|
|
bg_tile_map_select : int;
|
|
|
|
sprite_size : int;
|
|
|
|
sprite_enable : bool;
|
|
|
|
bg_display : bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
let get_lcd_control mem =
|
|
|
|
let b = Memory.get mem 0xFF40 |> int_of_char in
|
|
|
|
|
|
|
|
let lcd_display_enable = Bit.is_set b 7 in
|
|
|
|
let tile_map_select = if not (Bit.is_set b 6) then 0x9800 else 0x9c00 in
|
|
|
|
let window_display_enable = Bit.is_set b 5 in
|
|
|
|
let tile_data_select = if not (Bit.is_set b 4) then 0x8800 else 0x8000 in
|
|
|
|
let bg_tile_map_select = if not (Bit.is_set b 3) then 0x9800 else 0x9c00 in
|
|
|
|
let sprite_size = if not (Bit.is_set b 2) then 8 else 16 in
|
|
|
|
let sprite_enable = Bit.is_set b 1 in
|
|
|
|
let bg_display = Bit.is_set b 0 in
|
|
|
|
|
|
|
|
{
|
|
|
|
lcd_display_enable;
|
|
|
|
tile_map_select;
|
|
|
|
window_display_enable;
|
|
|
|
tile_data_select;
|
|
|
|
bg_tile_map_select;
|
|
|
|
sprite_size;
|
|
|
|
sprite_enable;
|
|
|
|
bg_display;
|
|
|
|
}
|
|
|
|
|
2015-03-25 16:20:06 +01:00
|
|
|
let init_screen w h =
|
|
|
|
{
|
|
|
|
width = w;
|
|
|
|
height = h;
|
|
|
|
data = Array.make_matrix h w { r = 255; g = 255; b = 255; a = 255 }
|
|
|
|
}
|
2015-04-19 19:18:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
let render_map mem map_addr =
|
|
|
|
let tile_size = 16 in
|
|
|
|
let map = Bytes.create (32 * 32 * tile_size) in
|
|
|
|
for y = 0 to (32 - 1) do
|
|
|
|
for x = 0 to (32 - 1) do
|
|
|
|
let tile_number = Memory.get mem (map_addr + (y * 32 + x)) |> int_of_char in
|
|
|
|
let src_offset = map_addr + tile_number * tile_size in
|
|
|
|
let tile_line_size = 2 in
|
|
|
|
let tile_height = 8 in
|
|
|
|
|
|
|
|
for line_index = 0 to (tile_height - 1) do
|
|
|
|
let line_offset = src_offset + (line_index * tile_line_size) in
|
|
|
|
let dst_y = y * tile_height + line_index in
|
|
|
|
let dst_offset = (dst_y * 32 + x) * tile_line_size in
|
|
|
|
Bytes.blit mem.vram line_offset map dst_offset tile_line_size
|
|
|
|
done
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
let render mem =
|
|
|
|
let
|
|
|
|
{
|
|
|
|
lcd_display_enable;
|
|
|
|
tile_map_select;
|
|
|
|
window_display_enable;
|
|
|
|
tile_data_select;
|
|
|
|
bg_tile_map_select;
|
|
|
|
sprite_size;
|
|
|
|
sprite_enable;
|
|
|
|
bg_display;
|
|
|
|
} = get_lcd_control mem in
|
|
|
|
let scy = Memory.get mem 0xFF42 |> int_of_char in
|
|
|
|
let scx = Memory.get mem 0xFF43 |> int_of_char in
|
|
|
|
scx + scy
|
|
|
|
|