22 Commits

Author SHA1 Message Date
9323addd1f Merge branch 'res-0-prerendered' into res-2-prerendered 2026-05-01 22:16:14 +02:00
70016dc7b7 create directional variations of ghost and robot sprites 2026-05-01 22:05:07 +02:00
dc42d7c5b6 Merge branch 'main' into res-0-prerendered 2026-05-01 21:53:28 +02:00
c88f67559d add minify flag to build script
(cherry picked from commit f0b43f7b7c)
2026-04-27 12:43:56 +02:00
f0b43f7b7c add minify flag to build script 2026-04-27 12:36:00 +02:00
cdc3a8e3a1 use decimal instead of binary representation to save space
(cherry picked from commit 54ba73c177)
2026-04-25 09:15:54 +02:00
2344a2e874 update branches description 2026-04-25 09:13:56 +02:00
54ba73c177 use decimal instead of binary representation to save space 2026-04-25 09:13:05 +02:00
d5e9dde21d use prerendered screen and remove sprite rotation
(cherry picked from commit 3783a98f95)
2026-04-25 08:59:04 +02:00
4e03aada20 update branches description 2026-04-25 07:38:02 +02:00
3783a98f95 use prerendered screen and remove sprite rotation 2026-04-25 07:35:00 +02:00
dc43e7aa0b improve sprites 2026-04-25 06:58:04 +02:00
c7360be7fa fix scene margin values 2026-04-25 06:51:26 +02:00
356cf3fb94 add colors: light gray and brown 2026-04-25 06:50:58 +02:00
b7bc9956f9 change which 8 bit color is used for dark gray 2026-04-25 06:41:56 +02:00
5231f54c27 add way to reduce build output's size 2026-04-25 05:36:20 +02:00
aad1fa45f7 add automatic padding in build script 2026-04-25 05:35:01 +02:00
88f10f9f06 replace texture jump table with dispatch table 2026-04-24 10:25:54 +02:00
6cdb7304c2 change the way static RAM variable are declared and used 2026-04-24 10:14:21 +02:00
e6b2d8b086 remove unused colors.asm const file 2026-04-24 10:14:21 +02:00
5588d4c29a update consts to reflect the new sprite size 2026-04-24 10:14:21 +02:00
e3cf5cdfa1 scale all sprites to 17x17 pixels 2026-04-24 10:14:21 +02:00
32 changed files with 111 additions and 360 deletions

BIN
assets/screen.ppm Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -15,9 +15,6 @@ const mapPath = "assets/map.ppm";
const spritesPath = { const spritesPath = {
"sprite_empty": "assets/sprites/empty.ppm", "sprite_empty": "assets/sprites/empty.ppm",
"sprite_unimplemented": "assets/sprites/placeholder.ppm", "sprite_unimplemented": "assets/sprites/placeholder.ppm",
"sprite_wall_end": "assets/sprites/wall_end.ppm",
"sprite_wall_straight": "assets/sprites/wall_straight.ppm",
"sprite_wall_corner": "assets/sprites/wall_corner.ppm",
"sprite_robot_up": "assets/sprites/robot_up.ppm", "sprite_robot_up": "assets/sprites/robot_up.ppm",
"sprite_robot_right": "assets/sprites/robot_right.ppm", "sprite_robot_right": "assets/sprites/robot_right.ppm",
"sprite_robot_down": "assets/sprites/robot_down.ppm", "sprite_robot_down": "assets/sprites/robot_down.ppm",
@@ -27,6 +24,7 @@ const spritesPath = {
"sprite_ghost_down": "assets/sprites/ghost_down.ppm", "sprite_ghost_down": "assets/sprites/ghost_down.ppm",
"sprite_ghost_left": "assets/sprites/ghost_left.ppm", "sprite_ghost_left": "assets/sprites/ghost_left.ppm",
"sprite_coin": "assets/sprites/coin.ppm", "sprite_coin": "assets/sprites/coin.ppm",
"screen": "assets/screen.ppm",
}; };
/** /**

View File

@@ -1,4 +1,3 @@
; map size 16x12 (or 15x11 with margins)
pub const map.width = 15 pub const map.width = 15
pub const map.height = 11 pub const map.height = 11
pub const map.size = 165 ; 11*15 pub const map.size = 165 ; 11*15

View File

@@ -1,8 +1,9 @@
; given: ; given:
; - 16x12 tiles map ; -> 256x192 pixels screen
; - 5x5 pixels tile ; -> 15x11 tiles map
; => 17x17 pixels tile
pub const scene.margin_top = 2 pub const scene.margin_top = 2
pub const scene.margin_bottom = 3 pub const scene.margin_bottom = 3
pub const scene.margin_left = 2 pub const scene.margin_left = 0
pub const scene.margin_right = 3 pub const scene.margin_right = 1

View File

@@ -20,7 +20,7 @@ pub const screen.mode_index = 0
pub const screen.mode_value = 2 pub const screen.mode_value = 2
pub const screen.offset_index = 1 pub const screen.offset_index = 1
pub const screen.resolution_index = 2 pub const screen.resolution_index = 2
pub const screen.resolution_value = 0 pub const screen.resolution_value = 2
pub const screen.width = 80 pub const screen.width = 256
pub const screen.height = 60 pub const screen.height = 192

View File

@@ -1,29 +1,21 @@
pub const sprites.width = 5 pub const sprites.width = 17
pub const sprites.height = 5 ; unused as sprite are all square pub const sprites.height = 17 ; unused as sprite are all square
pub const sprites.size = 25 ; height x width pub const sprites.size = 289 ; height x width
pub const sprites.rotation_0 = 0
pub const sprites.rotation_90 = 1
pub const sprites.rotation_180 = 2
pub const sprites.rotation_270 = 3
pub const sprites.empty = 0 ; must stay 0 (some code avoid addition when it knows the tile is empty) pub const sprites.empty = 0 ; must stay 0 (some code avoid addition when it knows the tile is empty)
pub const sprites.unimplemented = 1 pub const sprites.unimplemented = 1
pub const sprites.wall_end = 2
pub const sprites.wall_straight = 3
pub const sprites.wall_corner = 4
pub const sprites.robot = 5 pub const sprites.robot = 2
pub const sprites.robot_up = 5 pub const sprites.robot_up = 2
pub const sprites.robot_right = 6 pub const sprites.robot_right = 3
pub const sprites.robot_down = 7 pub const sprites.robot_down = 4
pub const sprites.robot_left = 8 pub const sprites.robot_left = 5
pub const sprites.ghost = 9 pub const sprites.ghost = 6
pub const sprites.ghost_up = 9 pub const sprites.ghost_up = 6
pub const sprites.ghost_right = 10 pub const sprites.ghost_right = 7
pub const sprites.ghost_down = 11 pub const sprites.ghost_down = 8
pub const sprites.ghost_left = 12 pub const sprites.ghost_left = 9
pub const sprites.coin = 13 pub const sprites.coin = 10
pub const sprites.max = 13 ; for lookup table pub const sprites.max = 10 ; for lookup table

52
src/init.asm Normal file
View File

@@ -0,0 +1,52 @@
;
; Jump table initialisation
;
; r1: sprite id
; r2: pointer address
; r3: pointer value
; sprite_empty
add r1, zr, sprites.empty
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_empty
store_32 [r2], r3
; sprite_unimplemented
add r1, zr, sprites.unimplemented
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_unimplemented
store_32 [r2], r3
; sprite_robot
add r1, zr, sprites.robot
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_robot
store_32 [r2], r3
; sprite_ghost
add r1, zr, sprites.ghost
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_ghost
store_32 [r2], r3
; sprite_coin
add r1, zr, sprites.coin
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_coin
store_32 [r2], r3
;
; Screen initialization
;
; r1 = screen parameter value
mov r1, screen.mode_index
screen r1, screen.mode_value
mov r1, screen.offset_index
add r2, zr, screen
screen r1, r2
mov r1, screen.resolution_index
screen r1, screen.resolution_value

View File

@@ -1,46 +1,3 @@
/* Draw the whole map (fill the screen memory with the values of the sprites based on the map)
Locals:
r1: x map coord
r2: y map coord
r3: sprite rotation
r4: sprite id
r12: rotation (returned by `sprite and rotation`)
r13: sprite (returned by `get_sprite_id_and_rotation`)
*/
pub drawing.draw_whole_map:
push r1
push r2
push r3
push r4
push r12
push r13
mov r1, 0
mov r2, 0
draw_whole_map_loop:
call sprite_rotation.get_sprite_id_and_rotation
mov r3, r12
mov r4, r13
call drawing.draw_sprite_at_map_coord
add r1, r1, 1
cmp r1, map.width
jne draw_whole_map_loop
mov r1, 0
add r2, r2, 1
cmp r2, map.height
jne draw_whole_map_loop
pop r13
pop r12
pop r4
pop r3
pop r2
pop r1
ret
/* Draw the tile corresponding to the given coordinate with it's map content /* Draw the tile corresponding to the given coordinate with it's map content
Inputs: Inputs:
@@ -83,7 +40,6 @@ pub drawing.clear_tile:
mov r1, r13 mov r1, r13
load_32 r2, [r9] load_32 r2, [r9]
mov r3, sprites.rotation_0
call draw_sprite call draw_sprite
pop r13 pop r13
@@ -118,7 +74,7 @@ get_tile_address:
cmp r3, sprites.height cmp r3, sprites.height
jne get_tile_address_offset_per_row_loop jne get_tile_address_offset_per_row_loop
add r13, zr, ptr.screen add r13, zr, screen
mov r3, 0 mov r3, 0
get_tile_address_margin_top_loop: get_tile_address_margin_top_loop:
@@ -186,8 +142,7 @@ get_sprite_address:
Inputs: Inputs:
r1: map x coord r1: map x coord
r2: map y coord r2: map y coord
r3: sprite rotation r3: sprite id
r4: sprite id
Locals: Locals:
r1: screen address r1: screen address
@@ -198,42 +153,36 @@ pub drawing.draw_sprite_at_map_coord:
push r1 push r1
push r2 push r2
push r3 push r3
push r4
push r13 push r13
call get_tile_address call get_tile_address
mov r1, r13 push r13
push r1
mov r1, r4 mov r1, r3
call get_sprite_address call get_sprite_address
mov r2, r13
pop r1
mov r2, r13
pop r13
mov r1, r13
call draw_sprite call draw_sprite
pop r13 pop r13
pop r4
pop r3 pop r3
pop r2 pop r2
pop r1 pop r1
ret ret
/* Draw given sprite (by address) at given screen position (by address) with given rotation /* Draw given sprite (by address) at given screen position (by address)
Inputs: Inputs:
r1: screen address r1: screen address
r2: sprite address r2: sprite address
r3: rotation
Locals: Locals:
r1: current screen pixel address r1: current screen pixel address
r4: x r2: current sprite pixel address
r5: y r3: x
r6: current sprite pixel address r4: color
r7: color r5: sprite last pixel address + 1
r8: x increment
r9: y increment
*/ */
draw_sprite: draw_sprite:
push r1 push r1
@@ -241,67 +190,25 @@ draw_sprite:
push r3 push r3
push r4 push r4
push r5 push r5
push r6
push r7
push r8
push r9
mov r6, r2
; rotation
draw_sprite_cmp_rotation_0:
cmp r3, sprites.rotation_0
jne draw_sprite_cmp_rotation_90
mov r8, 1
mov r9, 0
jmp draw_sprite_loop_init
draw_sprite_cmp_rotation_90:
cmp r3, sprites.rotation_90
jne draw_sprite_cmp_rotation_180
add r6, r6, sprites.size
sub r6, r6, sprites.width
sub r8, zr, sprites.width
mov r9, sprites.size
add r9, r9, 1
jmp draw_sprite_loop_init
draw_sprite_cmp_rotation_180:
cmp r3, sprites.rotation_180
jne draw_sprite_cmp_rotation_270
add r6, r6, sprites.size
sub r6, r6, 1
sub r8, zr, 1
mov r9, 0
jmp draw_sprite_loop_init
draw_sprite_cmp_rotation_270:
add r6, r6, sprites.width
sub r6, r6, 1
mov r8, sprites.width
sub r9, zr, sprites.size
sub r9, r9, 1
draw_sprite_loop_init: add r5, r2, sprites.size
mov r4, 0
mov r5, 0 mov r3, 0
draw_sprite_loop: draw_sprite_loop:
load_8 r7, [r6] load_8 r4, [r2]
store_8 [r1], r7 store_8 [r1], r4
add r4, r4, 1
add r1, r1, 1 add r1, r1, 1
add r6, r6, r8 add r2, r2, 1
cmp r4, sprites.width add r3, r3, 1
cmp r3, sprites.width
jne draw_sprite_loop jne draw_sprite_loop
mov r4, 0 mov r3, 0
add r6, r6, r9
add r1, r1, screen.width add r1, r1, screen.width
sub r1, r1, sprites.width sub r1, r1, sprites.width
add r5, r5, 1 cmp r5, r2
cmp r5, sprites.width
jne draw_sprite_loop jne draw_sprite_loop
pop r9
pop r8
pop r7
pop r6
pop r5 pop r5
pop r4 pop r4
pop r3 pop r3

View File

@@ -1,167 +0,0 @@
/* Return the sprite id and rotation for the given map coordinates
Inputs:
r1: x map coord
r2: y map coord
Outputs:
r12: sprite rotation
r13: sprite id
Locals:
r3: tile id
r4: map offset
r5: counter
r6: left tile id
r7: up tile id
r8: right tile id
r9: down tile id
*/
pub sprite_rotation.get_sprite_id_and_rotation:
push r1
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
add r4, r1, map
mov r5, 0
get_sprite_id_and_rotation_map_row_loop:
cmp r5, r2
je get_sprite_id_and_rotation_map_row_loop_end
add r4, r4, map.width
add r5, r5, 1
jmp get_sprite_id_and_rotation_map_row_loop
get_sprite_id_and_rotation_map_row_loop_end:
mov r12, sprites.rotation_0 ; default rotation
load_8 r3, [r4]
lsl r3, r3, 3 ; 2*instruction_size = *8 = <<3
add r3, r3, get_sprite_id_and_rotation_jump_table
jmp r3
get_sprite_id_and_rotation_jump_table:
; tile_empty
mov r13, sprites.empty
jmp get_sprite_id_and_rotation_return
; tiles_wall
jmp get_sprite_id_and_rotation_wall
nop
; tile_coin
mov r13, sprites.coin
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_wall:
mov r6, 0
mov r7, 0
mov r8, 0
mov r9, 0
get_sprite_id_and_rotation_cmp_left:
cmp r1, 0
je get_sprite_id_and_rotation_cmp_up
sub r4, r4, 1
load_8 r6, [r4]
add r4, r4, 1
get_sprite_id_and_rotation_cmp_up:
cmp r2, 0
je get_sprite_id_and_rotation_cmp_right
sub r4, r4, map.width
load_8 r7, [r4]
add r4, r4, map.width
get_sprite_id_and_rotation_cmp_right:
cmp r1, map.max_x
je get_sprite_id_and_rotation_cmp_down
add r4, r4, 1
load_8 r8, [r4]
sub r4, r4, 1
get_sprite_id_and_rotation_cmp_down:
cmp r2, map.max_y
je get_sprite_id_and_rotation_check_connections
add r4, r4, map.width
load_8 r9, [r4]
sub r4, r4, map.width
get_sprite_id_and_rotation_check_connections:
get_sprite_id_and_rotation_straight_0:
cmp r7, map.tiles.wall
jne get_sprite_id_and_rotation_straight_90
cmp r9, map.tiles.wall
jne get_sprite_id_and_rotation_straight_90
mov r12, sprites.rotation_0
mov r13, sprites.wall_straight
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_straight_90:
cmp r6, map.tiles.wall
jne get_sprite_id_and_rotation_corner_0
cmp r8, map.tiles.wall
jne get_sprite_id_and_rotation_corner_0
mov r12, sprites.rotation_90
mov r13, sprites.wall_straight
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_corner_0:
cmp r6, map.tiles.wall
jne get_sprite_id_and_rotation_corner_180
cmp r9, map.tiles.wall
jne get_sprite_id_and_rotation_corner_90
mov r12,sprites.rotation_0
mov r13, sprites.wall_corner
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_corner_90:
cmp r7, map.tiles.wall
jne get_sprite_id_and_rotation_end_90
mov r12,sprites.rotation_90
mov r13, sprites.wall_corner
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_corner_180:
cmp r8, map.tiles.wall
jne get_sprite_id_and_rotation_end_0
cmp r7, map.tiles.wall
jne get_sprite_id_and_rotation_corner_270
mov r12,sprites.rotation_180
mov r13, sprites.wall_corner
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_corner_270:
cmp r9, map.tiles.wall
jne get_sprite_id_and_rotation_end_270
mov r12,sprites.rotation_270
mov r13, sprites.wall_corner
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_end_0:
cmp r9, map.tiles.wall
jne get_sprite_id_and_rotation_end_180
mov r12,sprites.rotation_0
mov r13, sprites.wall_end
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_end_90:
mov r12,sprites.rotation_90
mov r13, sprites.wall_end
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_end_180:
mov r12,sprites.rotation_180
mov r13, sprites.wall_end
jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_end_270:
mov r12,sprites.rotation_270
mov r13, sprites.wall_end
;jmp get_sprite_id_and_rotation_return
get_sprite_id_and_rotation_return:
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
pop r1
ret

View File

@@ -9,8 +9,6 @@ include consts/sprites
include sections/init_sprite_lookup_table include sections/init_sprite_lookup_table
include sections/init_screen include sections/init_screen
call drawing.draw_whole_map
include sections/init_robot_state include sections/init_robot_state
include sections/init_ghost_state include sections/init_ghost_state
include sections/init_timers include sections/init_timers
@@ -47,13 +45,9 @@ jmp game_loop
include lib/u64 include lib/u64
include lib/game include lib/game
include lib/drawing include lib/drawing
include lib/sprite_rotation
include dist/empty include dist/empty
include dist/placeholder include dist/placeholder
include dist/wall_end
include dist/wall_straight
include dist/wall_corner
include dist/robot_up include dist/robot_up
include dist/robot_right include dist/robot_right
include dist/robot_down include dist/robot_down
@@ -67,3 +61,5 @@ include dist/coin
include dist/map include dist/map
include reserved_space include reserved_space
include dist/screen

View File

@@ -2,9 +2,6 @@
pub ptr.textures_addresses: pub ptr.textures_addresses:
U32 0 ; empty U32 0 ; empty
U32 0 ; placeholder U32 0 ; placeholder
U32 0 ; wall_end
U32 0 ; wall_straight
U32 0 ; wall_corner
U32 0 ; robot up U32 0 ; robot up
U32 0 ; robot right U32 0 ; robot right
U32 0 ; robot down U32 0 ; robot down
@@ -40,5 +37,3 @@ U8 0 ; x coord
U8 0 ; y coord U8 0 ; y coord
U8 0 ; direction U8 0 ; direction
U8 0 ; [padding] U8 0 ; [padding]
pub ptr.screen:

View File

@@ -12,6 +12,5 @@ store_8 [r6], r2
add r6, r6, 1 add r6, r6, 1
store_8 [r6], r5 store_8 [r6], r5
mov r3, sprites.rotation_0 mov r3, sprites.ghost_down
mov r4, sprites.ghost_down
call drawing.draw_sprite_at_map_coord call drawing.draw_sprite_at_map_coord

View File

@@ -12,6 +12,5 @@ store_8 [r6], r2
add r6, r6, 1 add r6, r6, 1
store_8 [r6], r5 store_8 [r6], r5
mov r3, sprites.rotation_0 mov r3, sprites.robot_down
mov r4, sprites.robot_down
call drawing.draw_sprite_at_map_coord call drawing.draw_sprite_at_map_coord

View File

@@ -3,7 +3,7 @@ mov r1, screen.mode_index
screen r1, screen.mode_value screen r1, screen.mode_value
mov r1, screen.offset_index mov r1, screen.offset_index
add r2, zr, ptr.screen add r2, zr, screen
screen r1, r2 screen r1, r2
mov r1, screen.resolution_index mov r1, screen.resolution_index

View File

@@ -17,24 +17,6 @@ lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses add r2, r2, ptr.textures_addresses
add r3, zr, sprite_unimplemented add r3, zr, sprite_unimplemented
store_32 [r2], r3 store_32 [r2], r3
; sprite_wall_end
add r1, zr, sprites.wall_end
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_wall_end
store_32 [r2], r3
; sprite_wall_straight
add r1, zr, sprites.wall_straight
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_wall_straight
store_32 [r2], r3
; sprite_wall_corner
add r1, zr, sprites.wall_corner
lsl r2, r1, arch.instruction_increment_shift
add r2, r2, ptr.textures_addresses
add r3, zr, sprite_wall_corner
store_32 [r2], r3
; sprite_robot_up ; sprite_robot_up
add r1, zr, sprites.robot_up add r1, zr, sprites.robot_up

View File

@@ -27,8 +27,8 @@ store_32 [r9], r6
/* Movement /* Movement
r1, r2: x, y r1, r2: x, y
r3: rotation r3: sprite id
r4: direction / sprite id r4: direction
r5, r6: increments x, y r5, r6: increments x, y
r7, r8: [RESERVED] r7, r8: [RESERVED]
r9: pointer r9: pointer
@@ -74,8 +74,7 @@ add r9, r9, 1
store_8 [r9], r2 store_8 [r9], r2
; draw ghost on new position ; draw ghost on new position
mov r3, sprites.rotation_0 add r3, r4, sprites.ghost
add r4, r4, sprites.ghost
call drawing.draw_sprite_at_map_coord call drawing.draw_sprite_at_map_coord
/* /*

View File

@@ -27,8 +27,8 @@ store_32 [r9], r6
/* Movement /* Movement
r1, r2: x, y r1, r2: x, y
r3: rotation r3: sprite id
r4: direction / sprite id r4: direction
r5, r6: increments x, y r5, r6: increments x, y
r7, r8: [RESERVED] r7, r8: [RESERVED]
r9: pointer r9: pointer
@@ -92,8 +92,7 @@ store_8 [r9], r2
pub timer_robot.draw: pub timer_robot.draw:
; draw robot on new position ; draw robot on new position
mov r3, sprites.rotation_0 add r3, r4, sprites.robot
add r4, r4, sprites.robot
call drawing.draw_sprite_at_map_coord call drawing.draw_sprite_at_map_coord
pub timer_robot.end: pub timer_robot.end:

View File

@@ -23,4 +23,4 @@ Resolution ID | Tile size (in pixels) | Comment
-- | -- | -- -- | -- | --
`0` | `5x5` | with a reminder of 5 pixels en width and 5 pixels in height. `0` | `5x5` | with a reminder of 5 pixels en width and 5 pixels in height.
`1` | `10x10` | with a reminder of 10w and 10h `1` | `10x10` | with a reminder of 10w and 10h
`2` | `17x17` | no reminder `2` | `17x17` | with a reminder of 1w and 5h