1// MIT License
2
3// Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com
4// Damien de Lemeny @ddelemeny // hello@ddelemeny.me
5
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22// SOFTWARE.
23
24#pragma once
25
26#include "tools.h"
27
28typedef struct
29{
30 u32 page_orig;
31 u32 bank_orig;
32 u32 nb_pages;
33 u32 bank_size;
34 u32 sheet_width;
35 u32 tile_width;
36 size_t ptr_size;
37 u8 (*peek)(const void*, u32);
38 void (*poke)(void*, u32, u8);
39} tic_blit_segment;
40
41typedef struct
42{
43 const tic_blit_segment* segment;
44 u8* ptr;
45} tic_tilesheet;
46
47typedef struct
48{
49 const tic_blit_segment* segment;
50 u32 offset;
51 u8* ptr;
52} tic_tileptr;
53
54tic_tilesheet tic_tilesheet_get(u8 segment, u8* ptr);
55tic_tileptr tic_tilesheet_gettile(const tic_tilesheet* sheet, s32 index, bool local);
56
57inline u8 tic_tilesheet_getpix(const tic_tilesheet* sheet, s32 x, s32 y)
58{
59 // tile coord
60 u16 tile_index = ((y >> 3) << 4 ) + (x / sheet->segment->tile_width);
61 // coord in tile
62 u32 pix_addr = ((x & (sheet->segment->tile_width - 1)) + ((y & 7) * sheet->segment->tile_width)) ;
63 return sheet->segment->peek(sheet->ptr+tile_index * sheet->segment->ptr_size, pix_addr);
64}
65
66inline void tic_tilesheet_setpix(const tic_tilesheet* sheet, s32 x, s32 y, u8 value)
67{
68 // tile coord
69 u16 tile_index = ((y >> 3) << 4 ) + (x / sheet->segment->tile_width);
70 // coord in tile
71 u32 pix_addr = ((x & (sheet->segment->tile_width - 1)) + ((y & 7) * sheet->segment->tile_width)) ;
72 sheet->segment->poke(sheet->ptr + tile_index * sheet->segment->ptr_size, pix_addr, value);
73}
74
75inline u8 tic_tilesheet_gettilepix(const tic_tileptr* tile, s32 x, s32 y)
76{
77 u32 addr = tile->offset + x + (y * tile->segment->tile_width);
78 return tile->segment->peek(tile->ptr, addr);
79}
80
81inline void tic_tilesheet_settilepix(const tic_tileptr* tile, s32 x, s32 y, u8 value)
82{
83 u32 addr = tile->offset + x + (y * tile->segment->tile_width);
84 tile->segment->poke(tile->ptr, addr, value);
85}
86
87typedef struct
88{
89 tic_bpp mode;
90 u8 pages;
91 u8 page;
92 u8 bank;
93} tic_blit;
94
95inline s32 tic_blit_calc_segment(const tic_blit* blit)
96{
97 return blit->pages * (2 + blit->bank) + blit->page;
98}
99
100inline void tic_blit_update_bpp(tic_blit* blit, tic_bpp bpp)
101{
102 blit->mode = bpp;
103 blit->pages = 4 / bpp;
104 blit->page %= blit->pages;
105}
106
107inline s32 tic_blit_calc_index(const tic_blit* blit)
108{
109 return blit->bank * blit->pages * TIC_BANK_SPRITES + blit->page * TIC_SPRITESHEET_COLS;
110}
111