diff --git a/assets/Rat/BMP_2_CAVE_DOWN_orig.png b/assets/Rat/BMP_2_CAVE_DOWN_orig.png new file mode 100644 index 0000000..bf80a88 Binary files /dev/null and b/assets/Rat/BMP_2_CAVE_DOWN_orig.png differ diff --git a/assets/Rat/BMP_2_CAVE_LEFT_orig.png b/assets/Rat/BMP_2_CAVE_LEFT_orig.png new file mode 100644 index 0000000..3cb676d Binary files /dev/null and b/assets/Rat/BMP_2_CAVE_LEFT_orig.png differ diff --git a/assets/Rat/BMP_2_CAVE_RIGHT_orig.png b/assets/Rat/BMP_2_CAVE_RIGHT_orig.png new file mode 100644 index 0000000..1ddf466 Binary files /dev/null and b/assets/Rat/BMP_2_CAVE_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_2_CAVE_UP_orig.png b/assets/Rat/BMP_2_CAVE_UP_orig.png new file mode 100644 index 0000000..ac92b22 Binary files /dev/null and b/assets/Rat/BMP_2_CAVE_UP_orig.png differ diff --git a/assets/Rat/BMP_2_EXPLOSION_DOWN_orig.png b/assets/Rat/BMP_2_EXPLOSION_DOWN_orig.png new file mode 100644 index 0000000..733d0fb Binary files /dev/null and b/assets/Rat/BMP_2_EXPLOSION_DOWN_orig.png differ diff --git a/assets/Rat/BMP_2_EXPLOSION_LEFT_orig.png b/assets/Rat/BMP_2_EXPLOSION_LEFT_orig.png new file mode 100644 index 0000000..7f5ca2e Binary files /dev/null and b/assets/Rat/BMP_2_EXPLOSION_LEFT_orig.png differ diff --git a/assets/Rat/BMP_2_EXPLOSION_RIGHT_orig.png b/assets/Rat/BMP_2_EXPLOSION_RIGHT_orig.png new file mode 100644 index 0000000..6cd616d Binary files /dev/null and b/assets/Rat/BMP_2_EXPLOSION_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_2_EXPLOSION_UP_orig.png b/assets/Rat/BMP_2_EXPLOSION_UP_orig.png new file mode 100644 index 0000000..c2a1425 Binary files /dev/null and b/assets/Rat/BMP_2_EXPLOSION_UP_orig.png differ diff --git a/assets/Rat/BMP_2_GAS_DOWN_orig.png b/assets/Rat/BMP_2_GAS_DOWN_orig.png new file mode 100644 index 0000000..de78bc9 Binary files /dev/null and b/assets/Rat/BMP_2_GAS_DOWN_orig.png differ diff --git a/assets/Rat/BMP_2_GAS_LEFT_orig.png b/assets/Rat/BMP_2_GAS_LEFT_orig.png new file mode 100644 index 0000000..b6c14b2 Binary files /dev/null and b/assets/Rat/BMP_2_GAS_LEFT_orig.png differ diff --git a/assets/Rat/BMP_2_GAS_RIGHT_orig.png b/assets/Rat/BMP_2_GAS_RIGHT_orig.png new file mode 100644 index 0000000..bf5d05f Binary files /dev/null and b/assets/Rat/BMP_2_GAS_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_2_GAS_UP_orig.png b/assets/Rat/BMP_2_GAS_UP_orig.png new file mode 100644 index 0000000..9b02c5d Binary files /dev/null and b/assets/Rat/BMP_2_GAS_UP_orig.png differ diff --git a/assets/Rat/BMP_3_CAVE_DOWN_orig.png b/assets/Rat/BMP_3_CAVE_DOWN_orig.png new file mode 100644 index 0000000..2943f5c Binary files /dev/null and b/assets/Rat/BMP_3_CAVE_DOWN_orig.png differ diff --git a/assets/Rat/BMP_3_CAVE_LEFT_orig.png b/assets/Rat/BMP_3_CAVE_LEFT_orig.png new file mode 100644 index 0000000..8fdb9fc Binary files /dev/null and b/assets/Rat/BMP_3_CAVE_LEFT_orig.png differ diff --git a/assets/Rat/BMP_3_CAVE_RIGHT_orig.png b/assets/Rat/BMP_3_CAVE_RIGHT_orig.png new file mode 100644 index 0000000..d3d50b2 Binary files /dev/null and b/assets/Rat/BMP_3_CAVE_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_3_CAVE_UP_orig.png b/assets/Rat/BMP_3_CAVE_UP_orig.png new file mode 100644 index 0000000..b233489 Binary files /dev/null and b/assets/Rat/BMP_3_CAVE_UP_orig.png differ diff --git a/assets/Rat/BMP_3_EXPLOSION_DOWN_orig.png b/assets/Rat/BMP_3_EXPLOSION_DOWN_orig.png new file mode 100644 index 0000000..f70c065 Binary files /dev/null and b/assets/Rat/BMP_3_EXPLOSION_DOWN_orig.png differ diff --git a/assets/Rat/BMP_3_EXPLOSION_LEFT_orig.png b/assets/Rat/BMP_3_EXPLOSION_LEFT_orig.png new file mode 100644 index 0000000..8bfab53 Binary files /dev/null and b/assets/Rat/BMP_3_EXPLOSION_LEFT_orig.png differ diff --git a/assets/Rat/BMP_3_EXPLOSION_RIGHT_orig.png b/assets/Rat/BMP_3_EXPLOSION_RIGHT_orig.png new file mode 100644 index 0000000..4788d23 Binary files /dev/null and b/assets/Rat/BMP_3_EXPLOSION_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_3_EXPLOSION_UP_orig.png b/assets/Rat/BMP_3_EXPLOSION_UP_orig.png new file mode 100644 index 0000000..be8e5b6 Binary files /dev/null and b/assets/Rat/BMP_3_EXPLOSION_UP_orig.png differ diff --git a/assets/Rat/BMP_3_GAS_DOWN_orig.png b/assets/Rat/BMP_3_GAS_DOWN_orig.png new file mode 100644 index 0000000..ec6a0aa Binary files /dev/null and b/assets/Rat/BMP_3_GAS_DOWN_orig.png differ diff --git a/assets/Rat/BMP_3_GAS_LEFT_orig.png b/assets/Rat/BMP_3_GAS_LEFT_orig.png new file mode 100644 index 0000000..304095a Binary files /dev/null and b/assets/Rat/BMP_3_GAS_LEFT_orig.png differ diff --git a/assets/Rat/BMP_3_GAS_RIGHT_orig.png b/assets/Rat/BMP_3_GAS_RIGHT_orig.png new file mode 100644 index 0000000..02ca880 Binary files /dev/null and b/assets/Rat/BMP_3_GAS_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_3_GAS_UP_orig.png b/assets/Rat/BMP_3_GAS_UP_orig.png new file mode 100644 index 0000000..e1df0de Binary files /dev/null and b/assets/Rat/BMP_3_GAS_UP_orig.png differ diff --git a/assets/Rat/BMP_4_CAVE_DOWN_orig.png b/assets/Rat/BMP_4_CAVE_DOWN_orig.png new file mode 100644 index 0000000..f3ea29e Binary files /dev/null and b/assets/Rat/BMP_4_CAVE_DOWN_orig.png differ diff --git a/assets/Rat/BMP_4_CAVE_LEFT_orig.png b/assets/Rat/BMP_4_CAVE_LEFT_orig.png new file mode 100644 index 0000000..88abe1f Binary files /dev/null and b/assets/Rat/BMP_4_CAVE_LEFT_orig.png differ diff --git a/assets/Rat/BMP_4_CAVE_RIGHT_orig.png b/assets/Rat/BMP_4_CAVE_RIGHT_orig.png new file mode 100644 index 0000000..24afeb4 Binary files /dev/null and b/assets/Rat/BMP_4_CAVE_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_4_CAVE_UP_orig.png b/assets/Rat/BMP_4_CAVE_UP_orig.png new file mode 100644 index 0000000..4708842 Binary files /dev/null and b/assets/Rat/BMP_4_CAVE_UP_orig.png differ diff --git a/assets/Rat/BMP_4_EXPLOSION_DOWN_orig.png b/assets/Rat/BMP_4_EXPLOSION_DOWN_orig.png new file mode 100644 index 0000000..06e908f Binary files /dev/null and b/assets/Rat/BMP_4_EXPLOSION_DOWN_orig.png differ diff --git a/assets/Rat/BMP_4_EXPLOSION_LEFT_orig.png b/assets/Rat/BMP_4_EXPLOSION_LEFT_orig.png new file mode 100644 index 0000000..1b0723b Binary files /dev/null and b/assets/Rat/BMP_4_EXPLOSION_LEFT_orig.png differ diff --git a/assets/Rat/BMP_4_EXPLOSION_RIGHT_orig.png b/assets/Rat/BMP_4_EXPLOSION_RIGHT_orig.png new file mode 100644 index 0000000..c1808b6 Binary files /dev/null and b/assets/Rat/BMP_4_EXPLOSION_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_4_EXPLOSION_UP_orig.png b/assets/Rat/BMP_4_EXPLOSION_UP_orig.png new file mode 100644 index 0000000..87ad445 Binary files /dev/null and b/assets/Rat/BMP_4_EXPLOSION_UP_orig.png differ diff --git a/assets/Rat/BMP_4_GAS_DOWN_orig.png b/assets/Rat/BMP_4_GAS_DOWN_orig.png new file mode 100644 index 0000000..ec37540 Binary files /dev/null and b/assets/Rat/BMP_4_GAS_DOWN_orig.png differ diff --git a/assets/Rat/BMP_4_GAS_LEFT_orig.png b/assets/Rat/BMP_4_GAS_LEFT_orig.png new file mode 100644 index 0000000..f8eca96 Binary files /dev/null and b/assets/Rat/BMP_4_GAS_LEFT_orig.png differ diff --git a/assets/Rat/BMP_4_GAS_RIGHT_orig.png b/assets/Rat/BMP_4_GAS_RIGHT_orig.png new file mode 100644 index 0000000..0a07f9f Binary files /dev/null and b/assets/Rat/BMP_4_GAS_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_4_GAS_UP_orig.png b/assets/Rat/BMP_4_GAS_UP_orig.png new file mode 100644 index 0000000..0670eeb Binary files /dev/null and b/assets/Rat/BMP_4_GAS_UP_orig.png differ diff --git a/assets/Rat/BMP_ARROW_DOWN_orig.png b/assets/Rat/BMP_ARROW_DOWN_orig.png new file mode 100644 index 0000000..6b18168 Binary files /dev/null and b/assets/Rat/BMP_ARROW_DOWN_orig.png differ diff --git a/assets/Rat/BMP_ARROW_LEFT_orig.png b/assets/Rat/BMP_ARROW_LEFT_orig.png new file mode 100644 index 0000000..eb08b5b Binary files /dev/null and b/assets/Rat/BMP_ARROW_LEFT_orig.png differ diff --git a/assets/Rat/BMP_ARROW_RIGHT_orig.png b/assets/Rat/BMP_ARROW_RIGHT_orig.png new file mode 100644 index 0000000..a9d78e8 Binary files /dev/null and b/assets/Rat/BMP_ARROW_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_ARROW_UP_orig.png b/assets/Rat/BMP_ARROW_UP_orig.png new file mode 100644 index 0000000..6e7f056 Binary files /dev/null and b/assets/Rat/BMP_ARROW_UP_orig.png differ diff --git a/assets/Rat/BMP_BABY_DOWN.png b/assets/Rat/BMP_BABY_DOWN.png index c4c1178..e2f3620 100644 Binary files a/assets/Rat/BMP_BABY_DOWN.png and b/assets/Rat/BMP_BABY_DOWN.png differ diff --git a/assets/Rat/BMP_BABY_LEFT.png b/assets/Rat/BMP_BABY_LEFT.png index f89a637..10cd94b 100644 Binary files a/assets/Rat/BMP_BABY_LEFT.png and b/assets/Rat/BMP_BABY_LEFT.png differ diff --git a/assets/Rat/BMP_BABY_RIGHT.png b/assets/Rat/BMP_BABY_RIGHT.png index bbed4d7..9b45230 100644 Binary files a/assets/Rat/BMP_BABY_RIGHT.png and b/assets/Rat/BMP_BABY_RIGHT.png differ diff --git a/assets/Rat/BMP_BABY_UP.png b/assets/Rat/BMP_BABY_UP.png index ed861ec..4199e3f 100644 Binary files a/assets/Rat/BMP_BABY_UP.png and b/assets/Rat/BMP_BABY_UP.png differ diff --git a/assets/Rat/BMP_EXPLOSION_DOWN_orig.png b/assets/Rat/BMP_EXPLOSION_DOWN_orig.png new file mode 100644 index 0000000..d30f732 Binary files /dev/null and b/assets/Rat/BMP_EXPLOSION_DOWN_orig.png differ diff --git a/assets/Rat/BMP_EXPLOSION_LEFT_orig.png b/assets/Rat/BMP_EXPLOSION_LEFT_orig.png new file mode 100644 index 0000000..b535a6d Binary files /dev/null and b/assets/Rat/BMP_EXPLOSION_LEFT_orig.png differ diff --git a/assets/Rat/BMP_EXPLOSION_RIGHT_orig.png b/assets/Rat/BMP_EXPLOSION_RIGHT_orig.png new file mode 100644 index 0000000..afa66f3 Binary files /dev/null and b/assets/Rat/BMP_EXPLOSION_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_EXPLOSION_UP_orig.png b/assets/Rat/BMP_EXPLOSION_UP_orig.png new file mode 100644 index 0000000..2940d22 Binary files /dev/null and b/assets/Rat/BMP_EXPLOSION_UP_orig.png differ diff --git a/assets/Rat/BMP_FEMALE_DOWN.png b/assets/Rat/BMP_FEMALE_DOWN.png index 4f9498d..0045ad7 100644 Binary files a/assets/Rat/BMP_FEMALE_DOWN.png and b/assets/Rat/BMP_FEMALE_DOWN.png differ diff --git a/assets/Rat/BMP_FEMALE_LEFT.png b/assets/Rat/BMP_FEMALE_LEFT.png index ba12af7..a9970ab 100644 Binary files a/assets/Rat/BMP_FEMALE_LEFT.png and b/assets/Rat/BMP_FEMALE_LEFT.png differ diff --git a/assets/Rat/BMP_FEMALE_RIGHT.png b/assets/Rat/BMP_FEMALE_RIGHT.png index 298ba35..8b8dbdf 100644 Binary files a/assets/Rat/BMP_FEMALE_RIGHT.png and b/assets/Rat/BMP_FEMALE_RIGHT.png differ diff --git a/assets/Rat/BMP_FEMALE_UP.png b/assets/Rat/BMP_FEMALE_UP.png index 4e6c556..fbf557c 100644 Binary files a/assets/Rat/BMP_FEMALE_UP.png and b/assets/Rat/BMP_FEMALE_UP.png differ diff --git a/assets/Rat/BMP_GAS_DOWN_orig.png b/assets/Rat/BMP_GAS_DOWN_orig.png new file mode 100644 index 0000000..90484ee Binary files /dev/null and b/assets/Rat/BMP_GAS_DOWN_orig.png differ diff --git a/assets/Rat/BMP_GAS_LEFT_orig.png b/assets/Rat/BMP_GAS_LEFT_orig.png new file mode 100644 index 0000000..7d64299 Binary files /dev/null and b/assets/Rat/BMP_GAS_LEFT_orig.png differ diff --git a/assets/Rat/BMP_GAS_RIGHT_orig.png b/assets/Rat/BMP_GAS_RIGHT_orig.png new file mode 100644 index 0000000..c6ae1a3 Binary files /dev/null and b/assets/Rat/BMP_GAS_RIGHT_orig.png differ diff --git a/assets/Rat/BMP_GAS_UP_orig.png b/assets/Rat/BMP_GAS_UP_orig.png new file mode 100644 index 0000000..0b274b5 Binary files /dev/null and b/assets/Rat/BMP_GAS_UP_orig.png differ diff --git a/assets/Rat/BMP_MALE_DOWN.png b/assets/Rat/BMP_MALE_DOWN.png index 419bb07..0366a17 100644 Binary files a/assets/Rat/BMP_MALE_DOWN.png and b/assets/Rat/BMP_MALE_DOWN.png differ diff --git a/assets/Rat/BMP_MALE_LEFT.png b/assets/Rat/BMP_MALE_LEFT.png index e6bf8bb..34adf72 100644 Binary files a/assets/Rat/BMP_MALE_LEFT.png and b/assets/Rat/BMP_MALE_LEFT.png differ diff --git a/assets/Rat/BMP_MALE_RIGHT.png b/assets/Rat/BMP_MALE_RIGHT.png index 9794bbc..2fdf66f 100644 Binary files a/assets/Rat/BMP_MALE_RIGHT.png and b/assets/Rat/BMP_MALE_RIGHT.png differ diff --git a/assets/Rat/BMP_MALE_UP.png b/assets/Rat/BMP_MALE_UP.png index e10677e..44c7e49 100644 Binary files a/assets/Rat/BMP_MALE_UP.png and b/assets/Rat/BMP_MALE_UP.png differ diff --git a/assets/Rat/BMP_START_1_DOWN_orig.png b/assets/Rat/BMP_START_1_DOWN_orig.png new file mode 100644 index 0000000..268a634 Binary files /dev/null and b/assets/Rat/BMP_START_1_DOWN_orig.png differ diff --git a/assets/Rat/BMP_START_2_DOWN_orig.png b/assets/Rat/BMP_START_2_DOWN_orig.png new file mode 100644 index 0000000..7f81391 Binary files /dev/null and b/assets/Rat/BMP_START_2_DOWN_orig.png differ diff --git a/assets/Rat/BMP_START_3_DOWN_orig.png b/assets/Rat/BMP_START_3_DOWN_orig.png new file mode 100644 index 0000000..9c3b552 Binary files /dev/null and b/assets/Rat/BMP_START_3_DOWN_orig.png differ diff --git a/assets/Rat/BMP_START_4_DOWN_orig.png b/assets/Rat/BMP_START_4_DOWN_orig.png new file mode 100644 index 0000000..810869d Binary files /dev/null and b/assets/Rat/BMP_START_4_DOWN_orig.png differ diff --git a/assets/Rat_Animated/MALE_DOWN_anim.png b/assets/Rat_Animated/MALE_DOWN_anim.png new file mode 100644 index 0000000..f09884f Binary files /dev/null and b/assets/Rat_Animated/MALE_DOWN_anim.png differ diff --git a/assets/Rat_Animated/MALE_LEFT_anim.png b/assets/Rat_Animated/MALE_LEFT_anim.png new file mode 100644 index 0000000..e1b6e02 Binary files /dev/null and b/assets/Rat_Animated/MALE_LEFT_anim.png differ diff --git a/assets/Rat_Animated/MALE_RIGHT_anim.png b/assets/Rat_Animated/MALE_RIGHT_anim.png new file mode 100644 index 0000000..480c805 Binary files /dev/null and b/assets/Rat_Animated/MALE_RIGHT_anim.png differ diff --git a/assets/Rat_Animated/MALE_UP_anim.png b/assets/Rat_Animated/MALE_UP_anim.png new file mode 100644 index 0000000..c7c2b21 Binary files /dev/null and b/assets/Rat_Animated/MALE_UP_anim.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_CAVE_DOWN.png b/assets/Rat_LPC_Style/BMP_1_CAVE_DOWN.png new file mode 100644 index 0000000..9aa5122 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_CAVE_DOWN.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_CAVE_LEFT.png b/assets/Rat_LPC_Style/BMP_1_CAVE_LEFT.png new file mode 100644 index 0000000..ada3777 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_CAVE_LEFT.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_CAVE_RIGHT.png b/assets/Rat_LPC_Style/BMP_1_CAVE_RIGHT.png new file mode 100644 index 0000000..72cacae Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_CAVE_RIGHT.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_CAVE_UP.png b/assets/Rat_LPC_Style/BMP_1_CAVE_UP.png new file mode 100644 index 0000000..20c2b0f Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_CAVE_UP.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_E.png b/assets/Rat_LPC_Style/BMP_1_E.png new file mode 100644 index 0000000..ab966c5 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_E.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_EN.png b/assets/Rat_LPC_Style/BMP_1_EN.png new file mode 100644 index 0000000..f9b70ad Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_EN.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_ES.png b/assets/Rat_LPC_Style/BMP_1_ES.png new file mode 100644 index 0000000..56f614b Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_ES.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_EXPLOSION_DOWN.png b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_DOWN.png new file mode 100644 index 0000000..876dd2c Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_DOWN.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_EXPLOSION_LEFT.png b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_LEFT.png new file mode 100644 index 0000000..0f09b6e Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_LEFT.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_EXPLOSION_RIGHT.png b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_RIGHT.png new file mode 100644 index 0000000..2820565 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_RIGHT.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_EXPLOSION_UP.png b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_UP.png new file mode 100644 index 0000000..df4b869 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_EXPLOSION_UP.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_FLOWER_1.png b/assets/Rat_LPC_Style/BMP_1_FLOWER_1.png new file mode 100644 index 0000000..46c8d71 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_FLOWER_1.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_FLOWER_2.png b/assets/Rat_LPC_Style/BMP_1_FLOWER_2.png new file mode 100644 index 0000000..8d23226 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_FLOWER_2.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_FLOWER_3.png b/assets/Rat_LPC_Style/BMP_1_FLOWER_3.png new file mode 100644 index 0000000..ad60b45 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_FLOWER_3.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_FLOWER_4.png b/assets/Rat_LPC_Style/BMP_1_FLOWER_4.png new file mode 100644 index 0000000..fc62cca Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_FLOWER_4.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GAS_DOWN.png b/assets/Rat_LPC_Style/BMP_1_GAS_DOWN.png new file mode 100644 index 0000000..4e0b520 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GAS_DOWN.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GAS_LEFT.png b/assets/Rat_LPC_Style/BMP_1_GAS_LEFT.png new file mode 100644 index 0000000..0e8df30 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GAS_LEFT.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GAS_RIGHT.png b/assets/Rat_LPC_Style/BMP_1_GAS_RIGHT.png new file mode 100644 index 0000000..919cd34 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GAS_RIGHT.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GAS_UP.png b/assets/Rat_LPC_Style/BMP_1_GAS_UP.png new file mode 100644 index 0000000..b8614af Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GAS_UP.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GRASS_1.png b/assets/Rat_LPC_Style/BMP_1_GRASS_1.png new file mode 100644 index 0000000..45b2d40 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GRASS_1.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GRASS_2.png b/assets/Rat_LPC_Style/BMP_1_GRASS_2.png new file mode 100644 index 0000000..7db02e7 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GRASS_2.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GRASS_3.png b/assets/Rat_LPC_Style/BMP_1_GRASS_3.png new file mode 100644 index 0000000..7728dff Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GRASS_3.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_GRASS_4.png b/assets/Rat_LPC_Style/BMP_1_GRASS_4.png new file mode 100644 index 0000000..642c71a Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_GRASS_4.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_N.png b/assets/Rat_LPC_Style/BMP_1_N.png new file mode 100644 index 0000000..a1aea7b Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_N.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_NE.png b/assets/Rat_LPC_Style/BMP_1_NE.png new file mode 100644 index 0000000..2ae5929 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_NE.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_NW.png b/assets/Rat_LPC_Style/BMP_1_NW.png new file mode 100644 index 0000000..191c33a Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_NW.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_S.png b/assets/Rat_LPC_Style/BMP_1_S.png new file mode 100644 index 0000000..37cfd89 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_S.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_SE.png b/assets/Rat_LPC_Style/BMP_1_SE.png new file mode 100644 index 0000000..219220b Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_SE.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_SW.png b/assets/Rat_LPC_Style/BMP_1_SW.png new file mode 100644 index 0000000..b9a32e4 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_SW.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_W.png b/assets/Rat_LPC_Style/BMP_1_W.png new file mode 100644 index 0000000..4adafaa Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_W.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_WN.png b/assets/Rat_LPC_Style/BMP_1_WN.png new file mode 100644 index 0000000..2a9494c Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_WN.png differ diff --git a/assets/Rat_LPC_Style/BMP_1_WS.png b/assets/Rat_LPC_Style/BMP_1_WS.png new file mode 100644 index 0000000..bb4cb14 Binary files /dev/null and b/assets/Rat_LPC_Style/BMP_1_WS.png differ diff --git a/engine/graphics.py b/engine/graphics.py index 8474b1a..acd66f6 100644 --- a/engine/graphics.py +++ b/engine/graphics.py @@ -44,14 +44,16 @@ class Graphics(): self.rat_assets[sex][direction] = self.render_engine.load_image( f"Rat/BMP_{sex}_{direction}.png", transparent_color=((125, 125, 125), (128, 128, 128)), + scale=False, ) texture = self.render_engine.load_image( f"Rat/BMP_{sex}_{direction}.png", transparent_color=((125, 125, 125), (128, 128, 128)), surface=False, + scale=False, ) self.rat_assets_textures[sex][direction] = texture - self.rat_image_sizes[sex][direction] = texture.size + self.rat_image_sizes[sex][direction] = (texture.size[0] // 4, texture.size[1]) for n in range(5): self.bomb_assets[n] = self.render_engine.load_image( diff --git a/engine/sdl2.py b/engine/sdl2.py index 59b9af3..b444f1b 100644 --- a/engine/sdl2.py +++ b/engine/sdl2.py @@ -243,7 +243,7 @@ class GameWindow: image = Image.new("RGBA", (width, height), (*color, 255)) return sdl2.ext.pillow_to_surface(image) - def load_image(self, path, transparent_color=None, surface=False): + def load_image(self, path, transparent_color=None, surface=False, scale=True): """Load and process an image with optional transparency and scaling""" image_path = resolve_bundle_path(os.path.join("assets", path)) image = Image.open(image_path) @@ -264,7 +264,8 @@ class GameWindow: image.putdata(new_data) # Scale image: tiles are now 64px (was 20px), multiply by 5/8 to reach cell_size (40px) - image = image.resize((image.width * 5 // 8, image.height * 5 // 8), Image.NEAREST) + if scale: + image = image.resize((image.width * 5 // 8, image.height * 5 // 8), Image.NEAREST) if surface: return sdl2.ext.pillow_to_surface(image) diff --git a/male_rats.png b/male_rats.png new file mode 100644 index 0000000..52276c5 Binary files /dev/null and b/male_rats.png differ diff --git a/male_rats_anim.png b/male_rats_anim.png new file mode 100644 index 0000000..ecd2cd0 Binary files /dev/null and b/male_rats_anim.png differ diff --git a/male_rats_anim_v2.png b/male_rats_anim_v2.png new file mode 100644 index 0000000..aa188c8 Binary files /dev/null and b/male_rats_anim_v2.png differ diff --git a/male_rats_anim_v4.png b/male_rats_anim_v4.png new file mode 100644 index 0000000..1ad97d3 Binary files /dev/null and b/male_rats_anim_v4.png differ diff --git a/male_rats_anim_v5.png b/male_rats_anim_v5.png new file mode 100644 index 0000000..13ab776 Binary files /dev/null and b/male_rats_anim_v5.png differ diff --git a/male_rats_anim_v6.png b/male_rats_anim_v6.png new file mode 100644 index 0000000..9ff4878 Binary files /dev/null and b/male_rats_anim_v6.png differ diff --git a/male_rats_anim_v7.png b/male_rats_anim_v7.png new file mode 100644 index 0000000..8b7d765 Binary files /dev/null and b/male_rats_anim_v7.png differ diff --git a/male_rats_anim_v8.png b/male_rats_anim_v8.png new file mode 100644 index 0000000..f718896 Binary files /dev/null and b/male_rats_anim_v8.png differ diff --git a/spritesheet.png b/spritesheet.png new file mode 100644 index 0000000..ba3ce7d Binary files /dev/null and b/spritesheet.png differ diff --git a/spritesheet_bmp1.png b/spritesheet_bmp1.png new file mode 100644 index 0000000..9b20cf3 Binary files /dev/null and b/spritesheet_bmp1.png differ diff --git a/spritesheet_bmp1_new.png b/spritesheet_bmp1_new.png new file mode 100644 index 0000000..59bbfec Binary files /dev/null and b/spritesheet_bmp1_new.png differ diff --git a/spritesheet_grass.png b/spritesheet_grass.png new file mode 100644 index 0000000..e52319c Binary files /dev/null and b/spritesheet_grass.png differ diff --git a/spritesheet_recolored.png b/spritesheet_recolored.png new file mode 100644 index 0000000..9865ada Binary files /dev/null and b/spritesheet_recolored.png differ diff --git a/spritesheet_restyle.png b/spritesheet_restyle.png new file mode 100644 index 0000000..8216841 Binary files /dev/null and b/spritesheet_restyle.png differ diff --git a/spritesheet_restyle_v10.png b/spritesheet_restyle_v10.png new file mode 100644 index 0000000..35697b1 Binary files /dev/null and b/spritesheet_restyle_v10.png differ diff --git a/spritesheet_restyle_v11.png b/spritesheet_restyle_v11.png new file mode 100644 index 0000000..8034e63 Binary files /dev/null and b/spritesheet_restyle_v11.png differ diff --git a/spritesheet_restyle_v12.png b/spritesheet_restyle_v12.png new file mode 100644 index 0000000..4e5befa Binary files /dev/null and b/spritesheet_restyle_v12.png differ diff --git a/spritesheet_restyle_v2.png b/spritesheet_restyle_v2.png new file mode 100644 index 0000000..50b53de Binary files /dev/null and b/spritesheet_restyle_v2.png differ diff --git a/spritesheet_restyle_v3.png b/spritesheet_restyle_v3.png new file mode 100644 index 0000000..b17d7e1 Binary files /dev/null and b/spritesheet_restyle_v3.png differ diff --git a/spritesheet_restyle_v4.png b/spritesheet_restyle_v4.png new file mode 100644 index 0000000..5ce4c1a Binary files /dev/null and b/spritesheet_restyle_v4.png differ diff --git a/spritesheet_restyle_v5.png b/spritesheet_restyle_v5.png new file mode 100644 index 0000000..f7ed4b4 Binary files /dev/null and b/spritesheet_restyle_v5.png differ diff --git a/spritesheet_restyle_v6.png b/spritesheet_restyle_v6.png new file mode 100644 index 0000000..434951a Binary files /dev/null and b/spritesheet_restyle_v6.png differ diff --git a/spritesheet_restyle_v7.png b/spritesheet_restyle_v7.png new file mode 100644 index 0000000..d09a3a7 Binary files /dev/null and b/spritesheet_restyle_v7.png differ diff --git a/spritesheet_restyle_v8.png b/spritesheet_restyle_v8.png new file mode 100644 index 0000000..34bc852 Binary files /dev/null and b/spritesheet_restyle_v8.png differ diff --git a/spritesheet_restyle_v9.png b/spritesheet_restyle_v9.png new file mode 100644 index 0000000..61f5b1a Binary files /dev/null and b/spritesheet_restyle_v9.png differ diff --git a/tools/lpc_extract/BMP_1_E.png b/tools/lpc_extract/BMP_1_E.png new file mode 100644 index 0000000..e0d345e Binary files /dev/null and b/tools/lpc_extract/BMP_1_E.png differ diff --git a/tools/lpc_extract/BMP_1_GRASS_1.png b/tools/lpc_extract/BMP_1_GRASS_1.png new file mode 100644 index 0000000..f116afb Binary files /dev/null and b/tools/lpc_extract/BMP_1_GRASS_1.png differ diff --git a/tools/lpc_extract/BMP_1_GRASS_1_scaled.png b/tools/lpc_extract/BMP_1_GRASS_1_scaled.png new file mode 100644 index 0000000..f116afb Binary files /dev/null and b/tools/lpc_extract/BMP_1_GRASS_1_scaled.png differ diff --git a/tools/lpc_extract/BMP_1_GRASS_1_tiled.png b/tools/lpc_extract/BMP_1_GRASS_1_tiled.png new file mode 100644 index 0000000..5b22526 Binary files /dev/null and b/tools/lpc_extract/BMP_1_GRASS_1_tiled.png differ diff --git a/tools/lpc_extract/BMP_1_GRASS_2.png b/tools/lpc_extract/BMP_1_GRASS_2.png new file mode 100644 index 0000000..f116afb Binary files /dev/null and b/tools/lpc_extract/BMP_1_GRASS_2.png differ diff --git a/tools/lpc_extract/BMP_1_GRASS_3.png b/tools/lpc_extract/BMP_1_GRASS_3.png new file mode 100644 index 0000000..f116afb Binary files /dev/null and b/tools/lpc_extract/BMP_1_GRASS_3.png differ diff --git a/tools/lpc_extract/BMP_1_GRASS_4.png b/tools/lpc_extract/BMP_1_GRASS_4.png new file mode 100644 index 0000000..f116afb Binary files /dev/null and b/tools/lpc_extract/BMP_1_GRASS_4.png differ diff --git a/tools/lpc_extract/BMP_1_N.png b/tools/lpc_extract/BMP_1_N.png new file mode 100644 index 0000000..b16c3fa Binary files /dev/null and b/tools/lpc_extract/BMP_1_N.png differ diff --git a/tools/lpc_extract/BMP_1_NE.png b/tools/lpc_extract/BMP_1_NE.png new file mode 100644 index 0000000..6007325 Binary files /dev/null and b/tools/lpc_extract/BMP_1_NE.png differ diff --git a/tools/lpc_extract/BMP_1_NW.png b/tools/lpc_extract/BMP_1_NW.png new file mode 100644 index 0000000..60c09f2 Binary files /dev/null and b/tools/lpc_extract/BMP_1_NW.png differ diff --git a/tools/lpc_extract/BMP_1_S.png b/tools/lpc_extract/BMP_1_S.png new file mode 100644 index 0000000..49b88b2 Binary files /dev/null and b/tools/lpc_extract/BMP_1_S.png differ diff --git a/tools/lpc_extract/BMP_1_SE.png b/tools/lpc_extract/BMP_1_SE.png new file mode 100644 index 0000000..1cb3256 Binary files /dev/null and b/tools/lpc_extract/BMP_1_SE.png differ diff --git a/tools/lpc_extract/BMP_1_SW.png b/tools/lpc_extract/BMP_1_SW.png new file mode 100644 index 0000000..5565b3e Binary files /dev/null and b/tools/lpc_extract/BMP_1_SW.png differ diff --git a/tools/lpc_extract/BMP_1_W.png b/tools/lpc_extract/BMP_1_W.png new file mode 100644 index 0000000..4b7f5c2 Binary files /dev/null and b/tools/lpc_extract/BMP_1_W.png differ diff --git a/tools/lpc_extract/analyze_colors.py b/tools/lpc_extract/analyze_colors.py new file mode 100644 index 0000000..f1937f9 --- /dev/null +++ b/tools/lpc_extract/analyze_colors.py @@ -0,0 +1,24 @@ +from PIL import Image +import glob +from collections import Counter + +files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +colors = Counter() + +for f in files: + img = Image.open(f).convert('RGB') + for pixel in img.getdata(): + colors[pixel] += 1 + +print("Original Colors:") +for c, count in colors.most_common(10): + print(c, count) + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGB') +lpc_colors = Counter() +for pixel in lpc_img.getdata(): + lpc_colors[pixel] += 1 + +print("\nLPC Colors:") +for c, count in lpc_colors.most_common(20): + print(c, count) diff --git a/tools/lpc_extract/analyze_edges.py b/tools/lpc_extract/analyze_edges.py new file mode 100644 index 0000000..1d92fb8 --- /dev/null +++ b/tools/lpc_extract/analyze_edges.py @@ -0,0 +1,22 @@ +import glob +from PIL import Image + +def analyze_edges(img_path): + img = Image.open(img_path).convert('RGB') + w, h = img.size + pixels = img.load() + + top = [pixels[x, 0] for x in range(w)] + bottom = [pixels[x, h-1] for x in range(w)] + left = [pixels[0, y] for y in range(h)] + right = [pixels[w-1, y] for y in range(h)] + + print(f"File: {img_path}") + print(f"Top edge unique colors: {set(top)}") + print(f"Bottom edge unique colors: {set(bottom)}") + print(f"Left edge unique colors: {set(left)}") + print(f"Right edge unique colors: {set(right)}") + print("---------------------------------") + +for f in ['BMP_1_GRASS_1.png', 'BMP_1_GRASS_2.png', 'BMP_1_N.png']: + analyze_edges(f'/tmp/orig_rat/{f}') diff --git a/tools/lpc_extract/animate_rat.py b/tools/lpc_extract/animate_rat.py new file mode 100644 index 0000000..6301d14 --- /dev/null +++ b/tools/lpc_extract/animate_rat.py @@ -0,0 +1,82 @@ +import os +import math +from PIL import Image + +def animate_tail(img, direction): + w, h = img.size + frames = [] + + pixels = img.load() + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h)) + fp = frame.load() + + # Copy original + for y in range(h): + for x in range(w): + fp[x, y] = pixels[x, y] + + # Define animation logic + # frame 0: center + # frame 1: left + # frame 2: center + # frame 3: right + + offset_mag = 0 + if frame_idx == 1: + offset_mag = -2 + elif frame_idx == 3: + offset_mag = 2 + + if offset_mag != 0: + # Clear frame + for y in range(h): + for x in range(w): + fp[x, y] = (0, 0, 0, 0) + + for y in range(h): + for x in range(w): + px = pixels[x, y] + if px[3] > 0: + nx, ny = x, y + + # Apply tail bending based on direction + if direction == 'UP': + if y > 40: # Tail area + factor = (y - 40) / 20.0 + nx = int(x + offset_mag * (factor**2)) + elif direction == 'DOWN': + if y < 24: # Tail area + factor = (24 - y) / 20.0 + nx = int(x + offset_mag * (factor**2)) + elif direction == 'LEFT': + if x > 40: + factor = (x - 40) / 20.0 + ny = int(y + offset_mag * (factor**2)) + elif direction == 'RIGHT': + if x < 24: + factor = (24 - x) / 20.0 + ny = int(y + offset_mag * (factor**2)) + + if 0 <= nx < w and 0 <= ny < h: + fp[nx, ny] = px + + frames.append(frame) + return frames + +os.makedirs('/home/enne2/dev/mice/assets/Rat_Animated', exist_ok=True) + +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + img = Image.open(f'/home/enne2/dev/mice/assets/Rat/BMP_MALE_{d}.png').convert('RGBA') + frames = animate_tail(img, d) + + # Create horizontal spritesheet + w, h = img.size + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(f'/home/enne2/dev/mice/assets/Rat_Animated/MALE_{d}_anim.png') + +print("Animations generated in Rat_Animated/") diff --git a/tools/lpc_extract/animate_rat_v2.py b/tools/lpc_extract/animate_rat_v2.py new file mode 100644 index 0000000..3ed2139 --- /dev/null +++ b/tools/lpc_extract/animate_rat_v2.py @@ -0,0 +1,76 @@ +import os +import math +from PIL import Image + +def animate_rat(img, direction): + w, h = img.size + frames = [] + + pixels = img.load() + + # Assuming background is (125, 125, 125) + bg_color = (125, 125, 125, 255) + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), bg_color) + fp = frame.load() + + offset_mag = 0 + bounce_y = 0 + + if frame_idx == 1: + offset_mag = -2 + bounce_y = -1 # Body moves UP (screen Y goes down) + elif frame_idx == 3: + offset_mag = 2 + bounce_y = -1 # Body moves UP + + for y in range(h): + for x in range(w): + px = pixels[x, y] + if px != bg_color and px[3] > 0: + is_tail = False + if direction == 'UP' and y > 40: is_tail = True + if direction == 'DOWN' and y < 24: is_tail = True + if direction == 'LEFT' and x > 40: is_tail = True + if direction == 'RIGHT' and x < 24: is_tail = True + + nx, ny = x, y + + if is_tail: + if direction == 'UP': + factor = (y - 40) / 20.0 + nx = int(x + offset_mag * (factor**1.5)) + elif direction == 'DOWN': + factor = (24 - y) / 20.0 + nx = int(x + offset_mag * (factor**1.5)) + elif direction == 'LEFT': + factor = (x - 40) / 20.0 + ny = int(y + offset_mag * (factor**1.5)) + elif direction == 'RIGHT': + factor = (24 - x) / 20.0 + ny = int(y + offset_mag * (factor**1.5)) + else: + # Body bounce + ny = y + bounce_y + + if 0 <= nx < w and 0 <= ny < h: + fp[nx, ny] = px + + frames.append(frame) + return frames + +os.makedirs('/home/enne2/dev/mice/assets/Rat_Animated', exist_ok=True) + +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + img = Image.open(f'/home/enne2/dev/mice/assets/Rat/BMP_MALE_{d}.png').convert('RGBA') + frames = animate_rat(img, d) + + w, h = img.size + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(f'/home/enne2/dev/mice/assets/Rat_Animated/MALE_{d}_anim.png') + +print("Animations with bounce generated!") diff --git a/tools/lpc_extract/animate_rat_v3.py b/tools/lpc_extract/animate_rat_v3.py new file mode 100644 index 0000000..0bc0e84 --- /dev/null +++ b/tools/lpc_extract/animate_rat_v3.py @@ -0,0 +1,121 @@ +import os +import math +from PIL import Image + +# Exact red pupil color +C_PUPIL = (202, 0, 0, 255) +C_WHITE = (255, 255, 255, 255) +C_BLACK = (0, 0, 0, 255) + +def animate_rat_v3(img, direction): + w, h = img.size + frames = [] + + pixels = img.load() + bg_color = (125, 125, 125, 255) + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), bg_color) + fp = frame.load() + + # Tail offset magnitude + offset_mag = 0 + bounce_y = 0 + eye_offset = (0, 0) + + if frame_idx == 1: + offset_mag = -5 # Much larger tail swing + bounce_y = -1 + # Saccades: shift pupils + if direction in ['UP', 'DOWN']: + eye_offset = (-1, 0) + else: + eye_offset = (0, -1) + + elif frame_idx == 3: + offset_mag = 5 + bounce_y = -1 + # Saccades: shift pupils + if direction in ['UP', 'DOWN']: + eye_offset = (1, 0) + else: + eye_offset = (0, 1) + + # First, copy the body and tail + for y in range(h): + for x in range(w): + px = pixels[x, y] + if px != bg_color and px[3] > 0 and px != C_PUPIL: + is_tail = False + if direction == 'UP' and y > 40: is_tail = True + if direction == 'DOWN' and y < 24: is_tail = True + if direction == 'LEFT' and x > 40: is_tail = True + if direction == 'RIGHT' and x < 24: is_tail = True + + nx, ny = x, y + + if is_tail: + if direction == 'UP': + factor = (y - 40) / 20.0 + nx = int(x + offset_mag * (factor**1.2)) + elif direction == 'DOWN': + factor = (24 - y) / 20.0 + nx = int(x + offset_mag * (factor**1.2)) + elif direction == 'LEFT': + factor = (x - 40) / 20.0 + ny = int(y + offset_mag * (factor**1.2)) + elif direction == 'RIGHT': + factor = (24 - x) / 20.0 + ny = int(y + offset_mag * (factor**1.2)) + else: + ny = y + bounce_y + + if 0 <= nx < w and 0 <= ny < h: + fp[nx, ny] = px + + # Now apply the pupils (Saccades) + for y in range(h): + for x in range(w): + px = pixels[x, y] + if px == C_PUPIL: + # Apply bounce to base position + bx, by = x, y + bounce_y + + # Apply saccade offset + ex, ey = bx + eye_offset[0], by + eye_offset[1] + + # Check if new position is on the white of the eye (using the shifted body coordinates) + # Actually, if we just draw it, it might overwrite the black border if it moves too far. + # Let's just draw it. + if 0 <= ex < w and 0 <= ey < h: + fp[ex, ey] = C_PUPIL + + # Fix: because we shifted the pupils, the old pupil location might be blank (bg_color) + # We need to fill any gaps in the white of the eye + for y in range(h): + for x in range(w): + if fp[x, y] == bg_color: + # If this pixel was originally white (shifted by bounce), fill it with white + orig_y = y - bounce_y + if 0 <= orig_y < h: + if pixels[x, orig_y] == C_WHITE or pixels[x, orig_y] == C_PUPIL: + # It's an eye gap + fp[x, y] = C_WHITE + + frames.append(frame) + return frames + +os.makedirs('/home/enne2/dev/mice/assets/Rat_Animated', exist_ok=True) + +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + img = Image.open(f'/home/enne2/dev/mice/assets/Rat/BMP_MALE_{d}.png').convert('RGBA') + frames = animate_rat_v3(img, d) + + w, h = img.size + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(f'/home/enne2/dev/mice/assets/Rat_Animated/MALE_{d}_anim.png') + +print("Animations with exaggerated tail and saccades generated!") diff --git a/tools/lpc_extract/animate_rat_v4.py b/tools/lpc_extract/animate_rat_v4.py new file mode 100644 index 0000000..b46e0f8 --- /dev/null +++ b/tools/lpc_extract/animate_rat_v4.py @@ -0,0 +1,82 @@ +import os +import math +from PIL import Image + +C_PUPIL = (202, 0, 0, 255) +C_WHITE = (255, 255, 255, 255) +C_BODY = (47, 96, 130, 255) + +def animate_rat_v4(img, direction): + w, h = img.size + frames = [] + + pixels = img.load() + bg_color = (125, 125, 125, 255) + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), bg_color) + fp = frame.load() + + offset_mag = 0 + bounce_y = 0 + is_blink = False + + if frame_idx == 1: + offset_mag = -8 # Exaggerated tail swing + bounce_y = -1 + elif frame_idx == 3: + offset_mag = 8 # Exaggerated tail swing + bounce_y = -1 + is_blink = True # Blink on this frame! + + for y in range(h): + for x in range(w): + px = pixels[x, y] + if px != bg_color and px[3] > 0: + is_tail = False + if direction == 'UP' and y > 40: is_tail = True + if direction == 'DOWN' and y < 24: is_tail = True + if direction == 'LEFT' and x > 40: is_tail = True + if direction == 'RIGHT' and x < 24: is_tail = True + + nx, ny = x, y + + if is_tail: + if direction == 'UP': + factor = (y - 40) / 20.0 + nx = int(x + offset_mag * (factor**1.8)) + elif direction == 'DOWN': + factor = (24 - y) / 20.0 + nx = int(x + offset_mag * (factor**1.8)) + elif direction == 'LEFT': + factor = (x - 40) / 20.0 + ny = int(y + offset_mag * (factor**1.8)) + elif direction == 'RIGHT': + factor = (24 - x) / 20.0 + ny = int(y + offset_mag * (factor**1.8)) + else: + ny = y + bounce_y + + if 0 <= nx < w and 0 <= ny < h: + if is_blink and px in [C_WHITE, C_PUPIL]: + fp[nx, ny] = C_BODY + else: + fp[nx, ny] = px + + frames.append(frame) + return frames + +os.makedirs('/home/enne2/dev/mice/assets/Rat_Animated', exist_ok=True) + +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + img = Image.open(f'/home/enne2/dev/mice/assets/Rat/BMP_MALE_{d}.png').convert('RGBA') + frames = animate_rat_v4(img, d) + + w, h = img.size + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(f'/home/enne2/dev/mice/assets/Rat_Animated/MALE_{d}_anim.png') + +print("Animations with blinking (chiusura occhi) and huge tail swing generated!") diff --git a/tools/lpc_extract/animate_rat_v5.py b/tools/lpc_extract/animate_rat_v5.py new file mode 100644 index 0000000..8dfe4ce --- /dev/null +++ b/tools/lpc_extract/animate_rat_v5.py @@ -0,0 +1,84 @@ +import os +import math +from PIL import Image + +C_PUPIL = (202, 0, 0, 255) +C_WHITE = (255, 255, 255, 255) +C_BODY = (47, 96, 130, 255) + +def animate_rat_v5(img, direction): + w, h = img.size + frames = [] + + pixels = img.load() + bg_color = (125, 125, 125, 255) + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), bg_color) + fp = frame.load() + + offset_mag = 0 + bounce_y = 0 + is_blink = False + + if frame_idx == 1: + offset_mag = -8 + bounce_y = -1 + elif frame_idx == 3: + offset_mag = 8 + bounce_y = -1 + is_blink = True + + for y in range(h): + for x in range(w): + px = pixels[x, y] + if px != bg_color and px[3] > 0: + is_tail = False + if direction == 'UP' and y > 40: is_tail = True + if direction == 'DOWN' and y < 24: is_tail = True + if direction == 'LEFT' and x > 40: is_tail = True + if direction == 'RIGHT' and x < 24: is_tail = True + + nx, ny = x, y + + if is_tail: + if direction == 'UP': + factor = (y - 40) / 20.0 + nx = int(x + offset_mag * (factor**1.8)) + ny = y + bounce_y # FIX: tail bounces too! + elif direction == 'DOWN': + factor = (24 - y) / 20.0 + nx = int(x + offset_mag * (factor**1.8)) + ny = y + bounce_y # FIX: tail bounces too! + elif direction == 'LEFT': + factor = (x - 40) / 20.0 + ny = int(y + offset_mag * (factor**1.8)) + bounce_y + elif direction == 'RIGHT': + factor = (24 - x) / 20.0 + ny = int(y + offset_mag * (factor**1.8)) + bounce_y + else: + ny = y + bounce_y + + if 0 <= nx < w and 0 <= ny < h: + if is_blink and px in [C_WHITE, C_PUPIL]: + fp[nx, ny] = C_BODY + else: + fp[nx, ny] = px + + frames.append(frame) + return frames + +os.makedirs('/home/enne2/dev/mice/assets/Rat_Animated', exist_ok=True) + +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + img = Image.open(f'/home/enne2/dev/mice/assets/Rat/BMP_MALE_{d}.png').convert('RGBA') + frames = animate_rat_v5(img, d) + + w, h = img.size + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(f'/home/enne2/dev/mice/assets/Rat_Animated/MALE_{d}_anim.png') + +print("Animations fixed: no more gap between tail and body!") diff --git a/tools/lpc_extract/bushes.png b/tools/lpc_extract/bushes.png new file mode 100644 index 0000000..48c274e Binary files /dev/null and b/tools/lpc_extract/bushes.png differ diff --git a/tools/lpc_extract/check_black.py b/tools/lpc_extract/check_black.py new file mode 100644 index 0000000..1960f51 --- /dev/null +++ b/tools/lpc_extract/check_black.py @@ -0,0 +1,9 @@ +from PIL import Image + +img = Image.open('/home/enne2/dev/mice/assets/Rat_LPC_Style/BMP_1_E.png').convert('RGBA') +pixels = img.load() +w, h = img.size +for x in range(w): + for y in range(h): + if pixels[x, y][:3] == (0, 0, 0): + print(f"Black at {x}, {y}: {pixels[x, y]}") diff --git a/tools/lpc_extract/check_rat.py b/tools/lpc_extract/check_rat.py new file mode 100644 index 0000000..5f2be7d --- /dev/null +++ b/tools/lpc_extract/check_rat.py @@ -0,0 +1,14 @@ +from PIL import Image +import os + +img = Image.open('/home/enne2/dev/mice/assets/Rat/BMP_MALE_UP.png').convert('RGBA') +pixels = img.load() +w, h = img.size + +print(f"Size: {w}x{h}") +colors = set() +for y in range(h): + for x in range(w): + if pixels[x,y][3] > 0: + colors.add(pixels[x,y]) +print("Colors:", colors) diff --git a/tools/lpc_extract/check_rat_size.py b/tools/lpc_extract/check_rat_size.py new file mode 100644 index 0000000..1e9b936 --- /dev/null +++ b/tools/lpc_extract/check_rat_size.py @@ -0,0 +1,4 @@ +from PIL import Image +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + img = Image.open(f'/home/enne2/dev/mice/assets/Rat/BMP_MALE_{d}.png') + print(f"{d}: {img.size}") diff --git a/tools/lpc_extract/check_screenshot.py b/tools/lpc_extract/check_screenshot.py new file mode 100644 index 0000000..0699559 --- /dev/null +++ b/tools/lpc_extract/check_screenshot.py @@ -0,0 +1,4 @@ +from PIL import Image + +img = Image.open('/home/enne2/dev/gameboy-hello/iso_test/doc/1719484435-screenshot.png').convert('RGB') +# wait, the image is at /home/enne2/.gemini/... no, it's not local. Let me find it! diff --git a/tools/lpc_extract/compare_bush_grass.py b/tools/lpc_extract/compare_bush_grass.py new file mode 100644 index 0000000..0275ea1 --- /dev/null +++ b/tools/lpc_extract/compare_bush_grass.py @@ -0,0 +1,11 @@ +from PIL import Image + +lpc = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') +grass = lpc.crop((4*32, 1*32, 5*32, 2*32)) +bush_center = lpc.crop((1*32, 1*32, 2*32, 2*32)) + +g_data = list(grass.getdata()) +b_data = list(bush_center.getdata()) + +diff = sum(1 for i in range(len(g_data)) if g_data[i] != b_data[i]) +print(f"Differences: {diff} pixels out of {len(g_data)}") diff --git a/tools/lpc_extract/extract.py b/tools/lpc_extract/extract.py new file mode 100644 index 0000000..e221fe6 --- /dev/null +++ b/tools/lpc_extract/extract.py @@ -0,0 +1,35 @@ +from PIL import Image + +# Load the source image +src_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +# Define a function to extract a 32x32 tile and scale it to 64x64 +def get_tile(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + img = src_img.crop(box) + return img.resize((64, 64), Image.NEAREST) + +# Create a dictionary of the files to create and their corresponding tiles +# Using some standard LPC terrain coordinates as a guess +tiles = { + 'BMP_1_GRASS_1.png': get_tile(4, 1), # center of grass-on-dirt + 'BMP_1_GRASS_2.png': get_tile(4, 1), + 'BMP_1_GRASS_3.png': get_tile(4, 1), + 'BMP_1_GRASS_4.png': get_tile(4, 1), + + # Let's extract some path edges for N, S, E, W + 'BMP_1_N.png': get_tile(4, 0), # Top edge of grass (dirt above) + 'BMP_1_S.png': get_tile(4, 2), # Bottom edge + 'BMP_1_E.png': get_tile(5, 1), # Right edge + 'BMP_1_W.png': get_tile(3, 1), # Left edge + + # Corners + 'BMP_1_NW.png': get_tile(3, 0), + 'BMP_1_NE.png': get_tile(5, 0), + 'BMP_1_SW.png': get_tile(3, 2), + 'BMP_1_SE.png': get_tile(5, 2), +} + +for name, img in tiles.items(): + img.save('/home/enne2/dev/mice/tools/lpc_extract/' + name) + print(f"Saved {name}") diff --git a/tools/lpc_extract/extract_all.py b/tools/lpc_extract/extract_all.py new file mode 100644 index 0000000..e80ebeb --- /dev/null +++ b/tools/lpc_extract/extract_all.py @@ -0,0 +1,16 @@ +from PIL import Image +import os + +src_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +os.makedirs('/home/enne2/dev/mice/tools/lpc_extract/grid', exist_ok=True) +cols = src_img.width // 32 +rows = src_img.height // 32 + +for ty in range(min(10, rows)): + for tx in range(min(10, cols)): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + tile = src_img.crop(box) + tile.save(f'/home/enne2/dev/mice/tools/lpc_extract/grid/{tx}_{ty}.png') + +print("Created grid tiles") diff --git a/tools/lpc_extract/extract_all2.py b/tools/lpc_extract/extract_all2.py new file mode 100644 index 0000000..2f133da --- /dev/null +++ b/tools/lpc_extract/extract_all2.py @@ -0,0 +1,21 @@ +from PIL import Image +import os + +src_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +cols = src_img.width // 32 +rows = src_img.height // 32 + +for ty in range(10, rows): + for tx in range(cols): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + tile = src_img.crop(box) + tile.save(f'/home/enne2/dev/mice/tools/lpc_extract/grid/{tx}_{ty}.png') + +for ty in range(10): + for tx in range(10, cols): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + tile = src_img.crop(box) + tile.save(f'/home/enne2/dev/mice/tools/lpc_extract/grid/{tx}_{ty}.png') + +print("Created rest of grid tiles") diff --git a/tools/lpc_extract/extract_grass.py b/tools/lpc_extract/extract_grass.py new file mode 100644 index 0000000..f537bba --- /dev/null +++ b/tools/lpc_extract/extract_grass.py @@ -0,0 +1,17 @@ +from PIL import Image +import os + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +os.makedirs('/home/enne2/dev/mice/tools/lpc_extract/grass_test', exist_ok=True) + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +# Let's extract some potential grass tiles. We know (4,1) is grass. +# It's likely part of a 3x3 block from (3,0) to (5,2) maybe? +for y in range(0, 4): + for x in range(3, 7): + tile = get_lpc_texture(x, y) + tile.save(f'/home/enne2/dev/mice/tools/lpc_extract/grass_test/tile_{x}_{y}.png') diff --git a/tools/lpc_extract/generate_all.py b/tools/lpc_extract/generate_all.py new file mode 100644 index 0000000..e668cf6 --- /dev/null +++ b/tools/lpc_extract/generate_all.py @@ -0,0 +1,90 @@ +from PIL import Image, ImageDraw +import os + +src_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') +out_dir = '/home/enne2/dev/mice/assets/Rat' + +def get_tile(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return src_img.crop(box) + +def scale(img): + return img.resize((64, 64), Image.NEAREST) + +# Grass variations (just use the same grass for now) +grass = get_tile(4, 1) +grass_scaled = scale(grass) +grass_scaled.save(os.path.join(out_dir, 'BMP_1_GRASS_1.png')) +grass_scaled.save(os.path.join(out_dir, 'BMP_1_GRASS_2.png')) +grass_scaled.save(os.path.join(out_dir, 'BMP_1_GRASS_3.png')) +grass_scaled.save(os.path.join(out_dir, 'BMP_1_GRASS_4.png')) + +# Paths +paths = { + 'BMP_1_N.png': (4, 0), + 'BMP_1_S.png': (4, 2), + 'BMP_1_E.png': (5, 1), + 'BMP_1_W.png': (3, 1), + 'BMP_1_NE.png': (5, 0), + 'BMP_1_NW.png': (3, 0), + 'BMP_1_SE.png': (5, 2), + 'BMP_1_SW.png': (3, 2), + 'BMP_1_WN.png': (3, 3), # dirt bottom-right + 'BMP_1_WS.png': (3, 4), # dirt top-right + 'BMP_1_EN.png': (4, 3), # dirt bottom-left + 'BMP_1_ES.png': (4, 4), # dirt top-left +} + +for name, (tx, ty) in paths.items(): + scale(get_tile(tx, ty)).save(os.path.join(out_dir, name)) + +# Flowers - draw simple flowers on grass +def make_flower(color, positions): + img = grass.copy() + draw = ImageDraw.Draw(img) + for px, py in positions: + draw.rectangle([px, py, px+2, py+2], fill=color) + return scale(img) + +make_flower((255, 255, 255), [(16, 16), (10, 20), (22, 10)]).save(os.path.join(out_dir, 'BMP_1_FLOWER_1.png')) # white +make_flower((255, 0, 0), [(10, 10), (20, 20), (14, 26)]).save(os.path.join(out_dir, 'BMP_1_FLOWER_2.png')) # red +make_flower((255, 100, 200), [(16, 16)]).save(os.path.join(out_dir, 'BMP_1_FLOWER_3.png')) # pink +make_flower((100, 200, 255), [(8, 8), (24, 24)]).save(os.path.join(out_dir, 'BMP_1_FLOWER_4.png')) # blue + +# Caves - draw black hole on dirt (tx=7, ty=1) +dirt = get_tile(7, 1) +def make_cave(direction): + img = dirt.copy() + draw = ImageDraw.Draw(img) + if direction == 'UP': + draw.pieslice([8, -16, 24, 16], 0, 180, fill=(0,0,0)) + elif direction == 'DOWN': + draw.pieslice([8, 16, 24, 48], 180, 360, fill=(0,0,0)) + elif direction == 'LEFT': + draw.pieslice([-16, 8, 16, 24], 270, 90, fill=(0,0,0)) + elif direction == 'RIGHT': + draw.pieslice([16, 8, 48, 24], 90, 270, fill=(0,0,0)) + return scale(img) + +make_cave('UP').save(os.path.join(out_dir, 'BMP_1_CAVE_UP.png')) +make_cave('DOWN').save(os.path.join(out_dir, 'BMP_1_CAVE_DOWN.png')) +make_cave('LEFT').save(os.path.join(out_dir, 'BMP_1_CAVE_LEFT.png')) +make_cave('RIGHT').save(os.path.join(out_dir, 'BMP_1_CAVE_RIGHT.png')) + +# Gas and Explosion +def make_fx(color, is_gas=False): + img = grass.copy() + draw = ImageDraw.Draw(img) + if is_gas: + draw.ellipse([4, 4, 28, 28], fill=(200, 200, 200, 200)) + draw.ellipse([8, 8, 20, 20], fill=(255, 255, 255, 220)) + else: + draw.ellipse([4, 4, 28, 28], fill=(255, 100, 0, 255)) + draw.ellipse([8, 8, 20, 20], fill=(255, 255, 0, 255)) + return scale(img) + +for d in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + make_fx(None, True).save(os.path.join(out_dir, f'BMP_1_GAS_{d}.png')) + make_fx(None, False).save(os.path.join(out_dir, f'BMP_1_EXPLOSION_{d}.png')) + +print("All 32 files generated.") diff --git a/tools/lpc_extract/generate_all_animations.py b/tools/lpc_extract/generate_all_animations.py new file mode 100644 index 0000000..fa0e295 --- /dev/null +++ b/tools/lpc_extract/generate_all_animations.py @@ -0,0 +1,101 @@ +import os +import math +from PIL import Image + +RAT_CONFIGS = { + 'MALE': { + 'C_PUPIL': (202, 0, 0, 255), + 'C_BODY': (47, 96, 130, 255) + }, + 'FEMALE': { + 'C_PUPIL': (255, 0, 0, 255), + 'C_BODY': (235, 94, 167, 255) + }, + 'BABY': { + 'C_PUPIL': None, + 'C_BODY': (192, 192, 192, 255) + } +} +C_WHITE = (255, 255, 255, 255) +C_BLACK = (0, 0, 0, 255) + +def generate_animation_v6(sex, direction, file_path): + config = RAT_CONFIGS[sex] + c_pupil = config['C_PUPIL'] + c_body = config['C_BODY'] + + img = Image.open(file_path.replace('.png', '_orig.png')).convert('RGBA') + w, h = img.size + frames = [] + + pixels = img.load() + bg_color = (125, 125, 125, 255) + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), bg_color) + fp = frame.load() + + offset_mag = 0 + bounce_y = 0 + is_blink = False + + if frame_idx == 1: + offset_mag = -8 + bounce_y = -1 + elif frame_idx == 3: + offset_mag = 8 + bounce_y = -1 + is_blink = True + + # Inverse mapping: for each destination pixel, find its source + for y in range(h): + for x in range(w): + src_x = x + src_y = y - bounce_y + + is_tail = False + if direction == 'UP' and src_y > 40: is_tail = True + if direction == 'DOWN' and src_y < 24: is_tail = True + if direction == 'LEFT' and src_x > 40: is_tail = True + if direction == 'RIGHT' and src_x < 24: is_tail = True + + if is_tail: + if direction == 'UP': + factor = (src_y - 40) / 20.0 + src_x = x - offset_mag * (factor**1.8) + elif direction == 'DOWN': + factor = (24 - src_y) / 20.0 + src_x = x - offset_mag * (factor**1.8) + elif direction == 'LEFT': + factor = (src_x - 40) / 20.0 + src_y = (y - bounce_y) - offset_mag * (factor**1.8) + elif direction == 'RIGHT': + factor = (24 - src_x) / 20.0 + src_y = (y - bounce_y) - offset_mag * (factor**1.8) + + # Nearest neighbor interpolation + src_x = int(round(src_x)) + src_y = int(round(src_y)) + + if 0 <= src_x < w and 0 <= src_y < h: + px = pixels[src_x, src_y] + if px != bg_color and px[3] > 0: + if is_blink and px in [C_WHITE, c_pupil]: + fp[x, y] = c_body + else: + fp[x, y] = px + + frames.append(frame) + + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(file_path) + print(f"Generated {file_path}") + +for sex in ['MALE', 'FEMALE', 'BABY']: + for direction in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + file_path = f'/home/enne2/dev/mice/assets/Rat/BMP_{sex}_{direction}.png' + if os.path.exists(file_path.replace('.png', '_orig.png')): + generate_animation_v6(sex, direction, file_path) diff --git a/tools/lpc_extract/generate_all_animations_v7.py b/tools/lpc_extract/generate_all_animations_v7.py new file mode 100644 index 0000000..a7c83bc --- /dev/null +++ b/tools/lpc_extract/generate_all_animations_v7.py @@ -0,0 +1,104 @@ +import os +import math +from PIL import Image + +RAT_CONFIGS = { + 'MALE': { + 'C_PUPIL': (202, 0, 0, 255), + 'C_BODY': (47, 96, 130, 255) + }, + 'FEMALE': { + 'C_PUPIL': (255, 0, 0, 255), + 'C_BODY': (235, 94, 167, 255) + }, + 'BABY': { + 'C_PUPIL': None, + 'C_BODY': (192, 192, 192, 255) + } +} +C_WHITE = (255, 255, 255, 255) +C_BLACK = (0, 0, 0, 255) + +def generate_animation_v7(sex, direction, file_path): + config = RAT_CONFIGS[sex] + c_pupil = config['C_PUPIL'] + c_body = config['C_BODY'] + + img = Image.open(file_path.replace('.png', '_orig.png')).convert('RGBA') + w, h = img.size + frames = [] + + pixels = img.load() + bg_color = (125, 125, 125, 255) + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), bg_color) + fp = frame.load() + + offset_mag = 0 + bounce_y = 0 + is_blink = False + + if frame_idx == 1: + offset_mag = -8 + bounce_y = -1 + elif frame_idx == 3: + offset_mag = 8 + bounce_y = -1 + is_blink = True + + for y in range(h): + for x in range(w): + src_x = x + src_y = y + + is_tail = False + if direction == 'UP' and y > 40: is_tail = True + if direction == 'DOWN' and y < 24: is_tail = True + if direction == 'LEFT' and x > 40: is_tail = True + if direction == 'RIGHT' and x < 24: is_tail = True + + # We calculate the shift for the current row (or column) + shift_x = 0 + shift_y = 0 + + if is_tail: + if direction == 'UP': + factor = (y - 40) / 20.0 + shift_x = int(round(offset_mag * (factor**1.8))) + elif direction == 'DOWN': + factor = (24 - y) / 20.0 + shift_x = int(round(offset_mag * (factor**1.8))) + elif direction == 'LEFT': + factor = (x - 40) / 20.0 + shift_y = int(round(offset_mag * (factor**1.8))) + elif direction == 'RIGHT': + factor = (24 - x) / 20.0 + shift_y = int(round(offset_mag * (factor**1.8))) + + # Apply the shift backward to find the source pixel + src_x = x - shift_x + src_y = y - shift_y - bounce_y + + if 0 <= src_x < w and 0 <= src_y < h: + px = pixels[src_x, src_y] + if px != bg_color and px[3] > 0: + if is_blink and px in [C_WHITE, c_pupil]: + fp[x, y] = c_body + else: + fp[x, y] = px + + frames.append(frame) + + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(file_path) + print(f"Generated {file_path}") + +for sex in ['MALE', 'FEMALE', 'BABY']: + for direction in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + file_path = f'/home/enne2/dev/mice/assets/Rat/BMP_{sex}_{direction}.png' + if os.path.exists(file_path.replace('.png', '_orig.png')): + generate_animation_v7(sex, direction, file_path) diff --git a/tools/lpc_extract/generate_all_animations_v8.py b/tools/lpc_extract/generate_all_animations_v8.py new file mode 100644 index 0000000..4f846ad --- /dev/null +++ b/tools/lpc_extract/generate_all_animations_v8.py @@ -0,0 +1,154 @@ +import os +import math +from PIL import Image + +RAT_CONFIGS = { + 'MALE': { + 'C_PUPIL': (202, 0, 0, 255), + 'C_BODY': (47, 96, 130, 255), + 'C_PINK': (254, 0, 241, 255) + }, + 'FEMALE': { + 'C_PUPIL': (255, 0, 0, 255), + 'C_BODY': (235, 94, 167, 255), + 'C_PINK': (128, 0, 128, 255) # or similar + }, + 'BABY': { + 'C_PUPIL': None, + 'C_BODY': (192, 192, 192, 255), + 'C_PINK': None + } +} +C_WHITE = (255, 255, 255, 255) +C_BLACK = (0, 0, 0, 255) +BG_COLOR = (125, 125, 125, 255) + +def get_color_priority(color, config): + if color[3] == 0 or color == BG_COLOR: return 0 + if color == C_BLACK: return 100 + if color == config.get('C_PUPIL'): return 90 + if color == C_WHITE: return 80 + if color == config.get('C_PINK'): return 70 + if color == config.get('C_BODY'): return 60 + return 50 + +def pixel_art_scale_down(img, config): + # Scale from 32x64 (or 64x32) down to 5/8 size (20x40 or 40x20) + w, h = img.size + nw, nh = w * 5 // 8, h * 5 // 8 + + scaled = Image.new('RGBA', (nw, nh), BG_COLOR) + sp = scaled.load() + ip = img.load() + + for dy in range(nh): + for dx in range(nw): + # map back to source range + sx1 = int(dx * 8 / 5) + sy1 = int(dy * 8 / 5) + sx2 = int((dx + 1) * 8 / 5) + sy2 = int((dy + 1) * 8 / 5) + + # ensure at least 1 pixel + if sx2 == sx1: sx2 += 1 + if sy2 == sy1: sy2 += 1 + + best_color = BG_COLOR + best_pri = 0 + + for y in range(sy1, min(sy2, h)): + for x in range(sx1, min(sx2, w)): + c = ip[x, y] + pri = get_color_priority(c, config) + if pri > best_pri: + best_pri = pri + best_color = c + + sp[dx, dy] = best_color + + return scaled + +def generate_animation_v8(sex, direction, file_path): + config = RAT_CONFIGS[sex] + c_pupil = config['C_PUPIL'] + c_body = config['C_BODY'] + + orig_img = Image.open(file_path.replace('.png', '_orig.png')).convert('RGBA') + + # Custom scale down BEFORE animation + img = pixel_art_scale_down(orig_img, config) + w, h = img.size + frames = [] + + pixels = img.load() + + for frame_idx in range(4): + frame = Image.new('RGBA', (w, h), BG_COLOR) + fp = frame.load() + + offset_mag = 0 + bounce_y = 0 + is_blink = False + + if frame_idx == 1: + offset_mag = -5 # reduced since width is smaller (was -8 for 32px, 5/8 * 8 = 5) + bounce_y = -1 + elif frame_idx == 3: + offset_mag = 5 + bounce_y = -1 + is_blink = True + + for y in range(h): + for x in range(w): + src_x = x + src_y = y + + is_tail = False + # Adjusted thresholds for 20x40 (was 40, now 25. Was 24, now 15) + if direction == 'UP' and y > 25: is_tail = True + if direction == 'DOWN' and y < 15: is_tail = True + if direction == 'LEFT' and x > 25: is_tail = True + if direction == 'RIGHT' and x < 15: is_tail = True + + shift_x = 0 + shift_y = 0 + + if is_tail: + if direction == 'UP': + factor = (y - 25) / 12.0 + shift_x = int(round(offset_mag * (factor**1.8))) + elif direction == 'DOWN': + factor = (15 - y) / 12.0 + shift_x = int(round(offset_mag * (factor**1.8))) + elif direction == 'LEFT': + factor = (x - 25) / 12.0 + shift_y = int(round(offset_mag * (factor**1.8))) + elif direction == 'RIGHT': + factor = (15 - x) / 12.0 + shift_y = int(round(offset_mag * (factor**1.8))) + + src_x = x - shift_x + src_y = y - shift_y - bounce_y + + if 0 <= src_x < w and 0 <= src_y < h: + px = pixels[src_x, src_y] + if px != BG_COLOR and px[3] > 0: + if is_blink and px in [C_WHITE, c_pupil]: + fp[x, y] = c_body + else: + fp[x, y] = px + + frames.append(frame) + + sheet = Image.new('RGBA', (w * 4, h)) + for i, f in enumerate(frames): + sheet.paste(f, (i * w, 0)) + + sheet.save(file_path) + print(f"Generated {file_path}") + +for sex in ['MALE', 'FEMALE', 'BABY']: + for direction in ['UP', 'DOWN', 'LEFT', 'RIGHT']: + file_path = f'/home/enne2/dev/mice/assets/Rat/BMP_{sex}_{direction}.png' + if os.path.exists(file_path.replace('.png', '_orig.png')): + generate_animation_v8(sex, direction, file_path) diff --git a/tools/lpc_extract/grass_montage.png b/tools/lpc_extract/grass_montage.png new file mode 100644 index 0000000..be38aa8 Binary files /dev/null and b/tools/lpc_extract/grass_montage.png differ diff --git a/tools/lpc_extract/grass_test/tile_3_0.png b/tools/lpc_extract/grass_test/tile_3_0.png new file mode 100644 index 0000000..b2c7a03 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_3_0.png differ diff --git a/tools/lpc_extract/grass_test/tile_3_1.png b/tools/lpc_extract/grass_test/tile_3_1.png new file mode 100644 index 0000000..e6bd79f Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_3_1.png differ diff --git a/tools/lpc_extract/grass_test/tile_3_2.png b/tools/lpc_extract/grass_test/tile_3_2.png new file mode 100644 index 0000000..2f7a2ab Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_3_2.png differ diff --git a/tools/lpc_extract/grass_test/tile_3_3.png b/tools/lpc_extract/grass_test/tile_3_3.png new file mode 100644 index 0000000..b729bb8 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_3_3.png differ diff --git a/tools/lpc_extract/grass_test/tile_4_0.png b/tools/lpc_extract/grass_test/tile_4_0.png new file mode 100644 index 0000000..771816c Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_4_0.png differ diff --git a/tools/lpc_extract/grass_test/tile_4_1.png b/tools/lpc_extract/grass_test/tile_4_1.png new file mode 100644 index 0000000..6e687f1 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_4_1.png differ diff --git a/tools/lpc_extract/grass_test/tile_4_2.png b/tools/lpc_extract/grass_test/tile_4_2.png new file mode 100644 index 0000000..fb6d612 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_4_2.png differ diff --git a/tools/lpc_extract/grass_test/tile_4_3.png b/tools/lpc_extract/grass_test/tile_4_3.png new file mode 100644 index 0000000..11ef425 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_4_3.png differ diff --git a/tools/lpc_extract/grass_test/tile_5_0.png b/tools/lpc_extract/grass_test/tile_5_0.png new file mode 100644 index 0000000..da361c1 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_5_0.png differ diff --git a/tools/lpc_extract/grass_test/tile_5_1.png b/tools/lpc_extract/grass_test/tile_5_1.png new file mode 100644 index 0000000..bbd0242 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_5_1.png differ diff --git a/tools/lpc_extract/grass_test/tile_5_2.png b/tools/lpc_extract/grass_test/tile_5_2.png new file mode 100644 index 0000000..5badc6f Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_5_2.png differ diff --git a/tools/lpc_extract/grass_test/tile_5_3.png b/tools/lpc_extract/grass_test/tile_5_3.png new file mode 100644 index 0000000..330c7de Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_5_3.png differ diff --git a/tools/lpc_extract/grass_test/tile_6_0.png b/tools/lpc_extract/grass_test/tile_6_0.png new file mode 100644 index 0000000..9646000 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_6_0.png differ diff --git a/tools/lpc_extract/grass_test/tile_6_1.png b/tools/lpc_extract/grass_test/tile_6_1.png new file mode 100644 index 0000000..e7f9cb3 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_6_1.png differ diff --git a/tools/lpc_extract/grass_test/tile_6_2.png b/tools/lpc_extract/grass_test/tile_6_2.png new file mode 100644 index 0000000..faf34cf Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_6_2.png differ diff --git a/tools/lpc_extract/grass_test/tile_6_3.png b/tools/lpc_extract/grass_test/tile_6_3.png new file mode 100644 index 0000000..6f468d8 Binary files /dev/null and b/tools/lpc_extract/grass_test/tile_6_3.png differ diff --git a/tools/lpc_extract/grid/0_0.png b/tools/lpc_extract/grid/0_0.png new file mode 100644 index 0000000..98f1d81 Binary files /dev/null and b/tools/lpc_extract/grid/0_0.png differ diff --git a/tools/lpc_extract/grid/0_1.png b/tools/lpc_extract/grid/0_1.png new file mode 100644 index 0000000..5ffbf49 Binary files /dev/null and b/tools/lpc_extract/grid/0_1.png differ diff --git a/tools/lpc_extract/grid/0_10.png b/tools/lpc_extract/grid/0_10.png new file mode 100644 index 0000000..932e44a Binary files /dev/null and b/tools/lpc_extract/grid/0_10.png differ diff --git a/tools/lpc_extract/grid/0_11.png b/tools/lpc_extract/grid/0_11.png new file mode 100644 index 0000000..438c2bb Binary files /dev/null and b/tools/lpc_extract/grid/0_11.png differ diff --git a/tools/lpc_extract/grid/0_12.png b/tools/lpc_extract/grid/0_12.png new file mode 100644 index 0000000..86e486f Binary files /dev/null and b/tools/lpc_extract/grid/0_12.png differ diff --git a/tools/lpc_extract/grid/0_13.png b/tools/lpc_extract/grid/0_13.png new file mode 100644 index 0000000..61ba961 Binary files /dev/null and b/tools/lpc_extract/grid/0_13.png differ diff --git a/tools/lpc_extract/grid/0_14.png b/tools/lpc_extract/grid/0_14.png new file mode 100644 index 0000000..d439b30 Binary files /dev/null and b/tools/lpc_extract/grid/0_14.png differ diff --git a/tools/lpc_extract/grid/0_15.png b/tools/lpc_extract/grid/0_15.png new file mode 100644 index 0000000..2028c86 Binary files /dev/null and b/tools/lpc_extract/grid/0_15.png differ diff --git a/tools/lpc_extract/grid/0_16.png b/tools/lpc_extract/grid/0_16.png new file mode 100644 index 0000000..a09f76e Binary files /dev/null and b/tools/lpc_extract/grid/0_16.png differ diff --git a/tools/lpc_extract/grid/0_17.png b/tools/lpc_extract/grid/0_17.png new file mode 100644 index 0000000..3f977d4 Binary files /dev/null and b/tools/lpc_extract/grid/0_17.png differ diff --git a/tools/lpc_extract/grid/0_18.png b/tools/lpc_extract/grid/0_18.png new file mode 100644 index 0000000..5889ace Binary files /dev/null and b/tools/lpc_extract/grid/0_18.png differ diff --git a/tools/lpc_extract/grid/0_19.png b/tools/lpc_extract/grid/0_19.png new file mode 100644 index 0000000..74731c2 Binary files /dev/null and b/tools/lpc_extract/grid/0_19.png differ diff --git a/tools/lpc_extract/grid/0_2.png b/tools/lpc_extract/grid/0_2.png new file mode 100644 index 0000000..7aad528 Binary files /dev/null and b/tools/lpc_extract/grid/0_2.png differ diff --git a/tools/lpc_extract/grid/0_20.png b/tools/lpc_extract/grid/0_20.png new file mode 100644 index 0000000..0b87826 Binary files /dev/null and b/tools/lpc_extract/grid/0_20.png differ diff --git a/tools/lpc_extract/grid/0_21.png b/tools/lpc_extract/grid/0_21.png new file mode 100644 index 0000000..e7ff073 Binary files /dev/null and b/tools/lpc_extract/grid/0_21.png differ diff --git a/tools/lpc_extract/grid/0_22.png b/tools/lpc_extract/grid/0_22.png new file mode 100644 index 0000000..f7ad387 Binary files /dev/null and b/tools/lpc_extract/grid/0_22.png differ diff --git a/tools/lpc_extract/grid/0_23.png b/tools/lpc_extract/grid/0_23.png new file mode 100644 index 0000000..0be1121 Binary files /dev/null and b/tools/lpc_extract/grid/0_23.png differ diff --git a/tools/lpc_extract/grid/0_24.png b/tools/lpc_extract/grid/0_24.png new file mode 100644 index 0000000..1ff5d5e Binary files /dev/null and b/tools/lpc_extract/grid/0_24.png differ diff --git a/tools/lpc_extract/grid/0_25.png b/tools/lpc_extract/grid/0_25.png new file mode 100644 index 0000000..c1ddee8 Binary files /dev/null and b/tools/lpc_extract/grid/0_25.png differ diff --git a/tools/lpc_extract/grid/0_3.png b/tools/lpc_extract/grid/0_3.png new file mode 100644 index 0000000..e401872 Binary files /dev/null and b/tools/lpc_extract/grid/0_3.png differ diff --git a/tools/lpc_extract/grid/0_4.png b/tools/lpc_extract/grid/0_4.png new file mode 100644 index 0000000..f510087 Binary files /dev/null and b/tools/lpc_extract/grid/0_4.png differ diff --git a/tools/lpc_extract/grid/0_5.png b/tools/lpc_extract/grid/0_5.png new file mode 100644 index 0000000..474e262 Binary files /dev/null and b/tools/lpc_extract/grid/0_5.png differ diff --git a/tools/lpc_extract/grid/0_6.png b/tools/lpc_extract/grid/0_6.png new file mode 100644 index 0000000..1c26b63 Binary files /dev/null and b/tools/lpc_extract/grid/0_6.png differ diff --git a/tools/lpc_extract/grid/0_7.png b/tools/lpc_extract/grid/0_7.png new file mode 100644 index 0000000..6175654 Binary files /dev/null and b/tools/lpc_extract/grid/0_7.png differ diff --git a/tools/lpc_extract/grid/0_8.png b/tools/lpc_extract/grid/0_8.png new file mode 100644 index 0000000..990b2c9 Binary files /dev/null and b/tools/lpc_extract/grid/0_8.png differ diff --git a/tools/lpc_extract/grid/0_9.png b/tools/lpc_extract/grid/0_9.png new file mode 100644 index 0000000..f7494ec Binary files /dev/null and b/tools/lpc_extract/grid/0_9.png differ diff --git a/tools/lpc_extract/grid/10_0.png b/tools/lpc_extract/grid/10_0.png new file mode 100644 index 0000000..3413dc0 Binary files /dev/null and b/tools/lpc_extract/grid/10_0.png differ diff --git a/tools/lpc_extract/grid/10_1.png b/tools/lpc_extract/grid/10_1.png new file mode 100644 index 0000000..5cf2704 Binary files /dev/null and b/tools/lpc_extract/grid/10_1.png differ diff --git a/tools/lpc_extract/grid/10_10.png b/tools/lpc_extract/grid/10_10.png new file mode 100644 index 0000000..2e5a1eb Binary files /dev/null and b/tools/lpc_extract/grid/10_10.png differ diff --git a/tools/lpc_extract/grid/10_11.png b/tools/lpc_extract/grid/10_11.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/10_11.png differ diff --git a/tools/lpc_extract/grid/10_12.png b/tools/lpc_extract/grid/10_12.png new file mode 100644 index 0000000..0707b3a Binary files /dev/null and b/tools/lpc_extract/grid/10_12.png differ diff --git a/tools/lpc_extract/grid/10_13.png b/tools/lpc_extract/grid/10_13.png new file mode 100644 index 0000000..fbb4936 Binary files /dev/null and b/tools/lpc_extract/grid/10_13.png differ diff --git a/tools/lpc_extract/grid/10_14.png b/tools/lpc_extract/grid/10_14.png new file mode 100644 index 0000000..61de286 Binary files /dev/null and b/tools/lpc_extract/grid/10_14.png differ diff --git a/tools/lpc_extract/grid/10_15.png b/tools/lpc_extract/grid/10_15.png new file mode 100644 index 0000000..e7a3d3d Binary files /dev/null and b/tools/lpc_extract/grid/10_15.png differ diff --git a/tools/lpc_extract/grid/10_16.png b/tools/lpc_extract/grid/10_16.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/10_16.png differ diff --git a/tools/lpc_extract/grid/10_17.png b/tools/lpc_extract/grid/10_17.png new file mode 100644 index 0000000..8c443a7 Binary files /dev/null and b/tools/lpc_extract/grid/10_17.png differ diff --git a/tools/lpc_extract/grid/10_18.png b/tools/lpc_extract/grid/10_18.png new file mode 100644 index 0000000..3db18d0 Binary files /dev/null and b/tools/lpc_extract/grid/10_18.png differ diff --git a/tools/lpc_extract/grid/10_19.png b/tools/lpc_extract/grid/10_19.png new file mode 100644 index 0000000..cd62909 Binary files /dev/null and b/tools/lpc_extract/grid/10_19.png differ diff --git a/tools/lpc_extract/grid/10_2.png b/tools/lpc_extract/grid/10_2.png new file mode 100644 index 0000000..6df9eae Binary files /dev/null and b/tools/lpc_extract/grid/10_2.png differ diff --git a/tools/lpc_extract/grid/10_20.png b/tools/lpc_extract/grid/10_20.png new file mode 100644 index 0000000..5238911 Binary files /dev/null and b/tools/lpc_extract/grid/10_20.png differ diff --git a/tools/lpc_extract/grid/10_21.png b/tools/lpc_extract/grid/10_21.png new file mode 100644 index 0000000..a4ce73e Binary files /dev/null and b/tools/lpc_extract/grid/10_21.png differ diff --git a/tools/lpc_extract/grid/10_22.png b/tools/lpc_extract/grid/10_22.png new file mode 100644 index 0000000..6ef3ce9 Binary files /dev/null and b/tools/lpc_extract/grid/10_22.png differ diff --git a/tools/lpc_extract/grid/10_23.png b/tools/lpc_extract/grid/10_23.png new file mode 100644 index 0000000..4502be9 Binary files /dev/null and b/tools/lpc_extract/grid/10_23.png differ diff --git a/tools/lpc_extract/grid/10_24.png b/tools/lpc_extract/grid/10_24.png new file mode 100644 index 0000000..f918c24 Binary files /dev/null and b/tools/lpc_extract/grid/10_24.png differ diff --git a/tools/lpc_extract/grid/10_25.png b/tools/lpc_extract/grid/10_25.png new file mode 100644 index 0000000..a9021bf Binary files /dev/null and b/tools/lpc_extract/grid/10_25.png differ diff --git a/tools/lpc_extract/grid/10_3.png b/tools/lpc_extract/grid/10_3.png new file mode 100644 index 0000000..1da3b7a Binary files /dev/null and b/tools/lpc_extract/grid/10_3.png differ diff --git a/tools/lpc_extract/grid/10_4.png b/tools/lpc_extract/grid/10_4.png new file mode 100644 index 0000000..fe19c7e Binary files /dev/null and b/tools/lpc_extract/grid/10_4.png differ diff --git a/tools/lpc_extract/grid/10_5.png b/tools/lpc_extract/grid/10_5.png new file mode 100644 index 0000000..a10da68 Binary files /dev/null and b/tools/lpc_extract/grid/10_5.png differ diff --git a/tools/lpc_extract/grid/10_6.png b/tools/lpc_extract/grid/10_6.png new file mode 100644 index 0000000..acb92c8 Binary files /dev/null and b/tools/lpc_extract/grid/10_6.png differ diff --git a/tools/lpc_extract/grid/10_7.png b/tools/lpc_extract/grid/10_7.png new file mode 100644 index 0000000..d0b7e58 Binary files /dev/null and b/tools/lpc_extract/grid/10_7.png differ diff --git a/tools/lpc_extract/grid/10_8.png b/tools/lpc_extract/grid/10_8.png new file mode 100644 index 0000000..68db211 Binary files /dev/null and b/tools/lpc_extract/grid/10_8.png differ diff --git a/tools/lpc_extract/grid/10_9.png b/tools/lpc_extract/grid/10_9.png new file mode 100644 index 0000000..72e45bf Binary files /dev/null and b/tools/lpc_extract/grid/10_9.png differ diff --git a/tools/lpc_extract/grid/11_0.png b/tools/lpc_extract/grid/11_0.png new file mode 100644 index 0000000..58df3c3 Binary files /dev/null and b/tools/lpc_extract/grid/11_0.png differ diff --git a/tools/lpc_extract/grid/11_1.png b/tools/lpc_extract/grid/11_1.png new file mode 100644 index 0000000..1857a3c Binary files /dev/null and b/tools/lpc_extract/grid/11_1.png differ diff --git a/tools/lpc_extract/grid/11_10.png b/tools/lpc_extract/grid/11_10.png new file mode 100644 index 0000000..d7ae693 Binary files /dev/null and b/tools/lpc_extract/grid/11_10.png differ diff --git a/tools/lpc_extract/grid/11_11.png b/tools/lpc_extract/grid/11_11.png new file mode 100644 index 0000000..6d4e838 Binary files /dev/null and b/tools/lpc_extract/grid/11_11.png differ diff --git a/tools/lpc_extract/grid/11_12.png b/tools/lpc_extract/grid/11_12.png new file mode 100644 index 0000000..9dc4bd8 Binary files /dev/null and b/tools/lpc_extract/grid/11_12.png differ diff --git a/tools/lpc_extract/grid/11_13.png b/tools/lpc_extract/grid/11_13.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_13.png differ diff --git a/tools/lpc_extract/grid/11_14.png b/tools/lpc_extract/grid/11_14.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_14.png differ diff --git a/tools/lpc_extract/grid/11_15.png b/tools/lpc_extract/grid/11_15.png new file mode 100644 index 0000000..79f502b Binary files /dev/null and b/tools/lpc_extract/grid/11_15.png differ diff --git a/tools/lpc_extract/grid/11_16.png b/tools/lpc_extract/grid/11_16.png new file mode 100644 index 0000000..e138f03 Binary files /dev/null and b/tools/lpc_extract/grid/11_16.png differ diff --git a/tools/lpc_extract/grid/11_17.png b/tools/lpc_extract/grid/11_17.png new file mode 100644 index 0000000..d645b7c Binary files /dev/null and b/tools/lpc_extract/grid/11_17.png differ diff --git a/tools/lpc_extract/grid/11_18.png b/tools/lpc_extract/grid/11_18.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_18.png differ diff --git a/tools/lpc_extract/grid/11_19.png b/tools/lpc_extract/grid/11_19.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_19.png differ diff --git a/tools/lpc_extract/grid/11_2.png b/tools/lpc_extract/grid/11_2.png new file mode 100644 index 0000000..0b569cf Binary files /dev/null and b/tools/lpc_extract/grid/11_2.png differ diff --git a/tools/lpc_extract/grid/11_20.png b/tools/lpc_extract/grid/11_20.png new file mode 100644 index 0000000..7d860be Binary files /dev/null and b/tools/lpc_extract/grid/11_20.png differ diff --git a/tools/lpc_extract/grid/11_21.png b/tools/lpc_extract/grid/11_21.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_21.png differ diff --git a/tools/lpc_extract/grid/11_22.png b/tools/lpc_extract/grid/11_22.png new file mode 100644 index 0000000..5870321 Binary files /dev/null and b/tools/lpc_extract/grid/11_22.png differ diff --git a/tools/lpc_extract/grid/11_23.png b/tools/lpc_extract/grid/11_23.png new file mode 100644 index 0000000..d4e41cb Binary files /dev/null and b/tools/lpc_extract/grid/11_23.png differ diff --git a/tools/lpc_extract/grid/11_24.png b/tools/lpc_extract/grid/11_24.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_24.png differ diff --git a/tools/lpc_extract/grid/11_25.png b/tools/lpc_extract/grid/11_25.png new file mode 100644 index 0000000..d99a584 Binary files /dev/null and b/tools/lpc_extract/grid/11_25.png differ diff --git a/tools/lpc_extract/grid/11_3.png b/tools/lpc_extract/grid/11_3.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_3.png differ diff --git a/tools/lpc_extract/grid/11_4.png b/tools/lpc_extract/grid/11_4.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_4.png differ diff --git a/tools/lpc_extract/grid/11_5.png b/tools/lpc_extract/grid/11_5.png new file mode 100644 index 0000000..20474a2 Binary files /dev/null and b/tools/lpc_extract/grid/11_5.png differ diff --git a/tools/lpc_extract/grid/11_6.png b/tools/lpc_extract/grid/11_6.png new file mode 100644 index 0000000..e9829c7 Binary files /dev/null and b/tools/lpc_extract/grid/11_6.png differ diff --git a/tools/lpc_extract/grid/11_7.png b/tools/lpc_extract/grid/11_7.png new file mode 100644 index 0000000..aa52314 Binary files /dev/null and b/tools/lpc_extract/grid/11_7.png differ diff --git a/tools/lpc_extract/grid/11_8.png b/tools/lpc_extract/grid/11_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_8.png differ diff --git a/tools/lpc_extract/grid/11_9.png b/tools/lpc_extract/grid/11_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/11_9.png differ diff --git a/tools/lpc_extract/grid/12_0.png b/tools/lpc_extract/grid/12_0.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_0.png differ diff --git a/tools/lpc_extract/grid/12_1.png b/tools/lpc_extract/grid/12_1.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_1.png differ diff --git a/tools/lpc_extract/grid/12_10.png b/tools/lpc_extract/grid/12_10.png new file mode 100644 index 0000000..a9bdd69 Binary files /dev/null and b/tools/lpc_extract/grid/12_10.png differ diff --git a/tools/lpc_extract/grid/12_11.png b/tools/lpc_extract/grid/12_11.png new file mode 100644 index 0000000..c6a65f1 Binary files /dev/null and b/tools/lpc_extract/grid/12_11.png differ diff --git a/tools/lpc_extract/grid/12_12.png b/tools/lpc_extract/grid/12_12.png new file mode 100644 index 0000000..5f4e4ea Binary files /dev/null and b/tools/lpc_extract/grid/12_12.png differ diff --git a/tools/lpc_extract/grid/12_13.png b/tools/lpc_extract/grid/12_13.png new file mode 100644 index 0000000..7e8bbc9 Binary files /dev/null and b/tools/lpc_extract/grid/12_13.png differ diff --git a/tools/lpc_extract/grid/12_14.png b/tools/lpc_extract/grid/12_14.png new file mode 100644 index 0000000..b949498 Binary files /dev/null and b/tools/lpc_extract/grid/12_14.png differ diff --git a/tools/lpc_extract/grid/12_15.png b/tools/lpc_extract/grid/12_15.png new file mode 100644 index 0000000..7b738ce Binary files /dev/null and b/tools/lpc_extract/grid/12_15.png differ diff --git a/tools/lpc_extract/grid/12_16.png b/tools/lpc_extract/grid/12_16.png new file mode 100644 index 0000000..96e36f2 Binary files /dev/null and b/tools/lpc_extract/grid/12_16.png differ diff --git a/tools/lpc_extract/grid/12_17.png b/tools/lpc_extract/grid/12_17.png new file mode 100644 index 0000000..5af3bf9 Binary files /dev/null and b/tools/lpc_extract/grid/12_17.png differ diff --git a/tools/lpc_extract/grid/12_18.png b/tools/lpc_extract/grid/12_18.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_18.png differ diff --git a/tools/lpc_extract/grid/12_19.png b/tools/lpc_extract/grid/12_19.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_19.png differ diff --git a/tools/lpc_extract/grid/12_2.png b/tools/lpc_extract/grid/12_2.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_2.png differ diff --git a/tools/lpc_extract/grid/12_20.png b/tools/lpc_extract/grid/12_20.png new file mode 100644 index 0000000..c62cc53 Binary files /dev/null and b/tools/lpc_extract/grid/12_20.png differ diff --git a/tools/lpc_extract/grid/12_21.png b/tools/lpc_extract/grid/12_21.png new file mode 100644 index 0000000..679f2cc Binary files /dev/null and b/tools/lpc_extract/grid/12_21.png differ diff --git a/tools/lpc_extract/grid/12_22.png b/tools/lpc_extract/grid/12_22.png new file mode 100644 index 0000000..19be177 Binary files /dev/null and b/tools/lpc_extract/grid/12_22.png differ diff --git a/tools/lpc_extract/grid/12_23.png b/tools/lpc_extract/grid/12_23.png new file mode 100644 index 0000000..68263a6 Binary files /dev/null and b/tools/lpc_extract/grid/12_23.png differ diff --git a/tools/lpc_extract/grid/12_24.png b/tools/lpc_extract/grid/12_24.png new file mode 100644 index 0000000..cfcfdef Binary files /dev/null and b/tools/lpc_extract/grid/12_24.png differ diff --git a/tools/lpc_extract/grid/12_25.png b/tools/lpc_extract/grid/12_25.png new file mode 100644 index 0000000..afb997e Binary files /dev/null and b/tools/lpc_extract/grid/12_25.png differ diff --git a/tools/lpc_extract/grid/12_3.png b/tools/lpc_extract/grid/12_3.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_3.png differ diff --git a/tools/lpc_extract/grid/12_4.png b/tools/lpc_extract/grid/12_4.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_4.png differ diff --git a/tools/lpc_extract/grid/12_5.png b/tools/lpc_extract/grid/12_5.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_5.png differ diff --git a/tools/lpc_extract/grid/12_6.png b/tools/lpc_extract/grid/12_6.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_6.png differ diff --git a/tools/lpc_extract/grid/12_7.png b/tools/lpc_extract/grid/12_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_7.png differ diff --git a/tools/lpc_extract/grid/12_8.png b/tools/lpc_extract/grid/12_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_8.png differ diff --git a/tools/lpc_extract/grid/12_9.png b/tools/lpc_extract/grid/12_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/12_9.png differ diff --git a/tools/lpc_extract/grid/13_0.png b/tools/lpc_extract/grid/13_0.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_0.png differ diff --git a/tools/lpc_extract/grid/13_1.png b/tools/lpc_extract/grid/13_1.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_1.png differ diff --git a/tools/lpc_extract/grid/13_10.png b/tools/lpc_extract/grid/13_10.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_10.png differ diff --git a/tools/lpc_extract/grid/13_11.png b/tools/lpc_extract/grid/13_11.png new file mode 100644 index 0000000..70867e6 Binary files /dev/null and b/tools/lpc_extract/grid/13_11.png differ diff --git a/tools/lpc_extract/grid/13_12.png b/tools/lpc_extract/grid/13_12.png new file mode 100644 index 0000000..50f45ce Binary files /dev/null and b/tools/lpc_extract/grid/13_12.png differ diff --git a/tools/lpc_extract/grid/13_13.png b/tools/lpc_extract/grid/13_13.png new file mode 100644 index 0000000..8259961 Binary files /dev/null and b/tools/lpc_extract/grid/13_13.png differ diff --git a/tools/lpc_extract/grid/13_14.png b/tools/lpc_extract/grid/13_14.png new file mode 100644 index 0000000..0a0cca0 Binary files /dev/null and b/tools/lpc_extract/grid/13_14.png differ diff --git a/tools/lpc_extract/grid/13_15.png b/tools/lpc_extract/grid/13_15.png new file mode 100644 index 0000000..dcd091a Binary files /dev/null and b/tools/lpc_extract/grid/13_15.png differ diff --git a/tools/lpc_extract/grid/13_16.png b/tools/lpc_extract/grid/13_16.png new file mode 100644 index 0000000..68ddf79 Binary files /dev/null and b/tools/lpc_extract/grid/13_16.png differ diff --git a/tools/lpc_extract/grid/13_17.png b/tools/lpc_extract/grid/13_17.png new file mode 100644 index 0000000..1a0cbfc Binary files /dev/null and b/tools/lpc_extract/grid/13_17.png differ diff --git a/tools/lpc_extract/grid/13_18.png b/tools/lpc_extract/grid/13_18.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_18.png differ diff --git a/tools/lpc_extract/grid/13_19.png b/tools/lpc_extract/grid/13_19.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_19.png differ diff --git a/tools/lpc_extract/grid/13_2.png b/tools/lpc_extract/grid/13_2.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_2.png differ diff --git a/tools/lpc_extract/grid/13_20.png b/tools/lpc_extract/grid/13_20.png new file mode 100644 index 0000000..c004687 Binary files /dev/null and b/tools/lpc_extract/grid/13_20.png differ diff --git a/tools/lpc_extract/grid/13_21.png b/tools/lpc_extract/grid/13_21.png new file mode 100644 index 0000000..12c2e0a Binary files /dev/null and b/tools/lpc_extract/grid/13_21.png differ diff --git a/tools/lpc_extract/grid/13_22.png b/tools/lpc_extract/grid/13_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_22.png differ diff --git a/tools/lpc_extract/grid/13_23.png b/tools/lpc_extract/grid/13_23.png new file mode 100644 index 0000000..be237bd Binary files /dev/null and b/tools/lpc_extract/grid/13_23.png differ diff --git a/tools/lpc_extract/grid/13_24.png b/tools/lpc_extract/grid/13_24.png new file mode 100644 index 0000000..3311964 Binary files /dev/null and b/tools/lpc_extract/grid/13_24.png differ diff --git a/tools/lpc_extract/grid/13_25.png b/tools/lpc_extract/grid/13_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_25.png differ diff --git a/tools/lpc_extract/grid/13_3.png b/tools/lpc_extract/grid/13_3.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_3.png differ diff --git a/tools/lpc_extract/grid/13_4.png b/tools/lpc_extract/grid/13_4.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_4.png differ diff --git a/tools/lpc_extract/grid/13_5.png b/tools/lpc_extract/grid/13_5.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_5.png differ diff --git a/tools/lpc_extract/grid/13_6.png b/tools/lpc_extract/grid/13_6.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_6.png differ diff --git a/tools/lpc_extract/grid/13_7.png b/tools/lpc_extract/grid/13_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_7.png differ diff --git a/tools/lpc_extract/grid/13_8.png b/tools/lpc_extract/grid/13_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_8.png differ diff --git a/tools/lpc_extract/grid/13_9.png b/tools/lpc_extract/grid/13_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/13_9.png differ diff --git a/tools/lpc_extract/grid/14_0.png b/tools/lpc_extract/grid/14_0.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_0.png differ diff --git a/tools/lpc_extract/grid/14_1.png b/tools/lpc_extract/grid/14_1.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_1.png differ diff --git a/tools/lpc_extract/grid/14_10.png b/tools/lpc_extract/grid/14_10.png new file mode 100644 index 0000000..9c21ad1 Binary files /dev/null and b/tools/lpc_extract/grid/14_10.png differ diff --git a/tools/lpc_extract/grid/14_11.png b/tools/lpc_extract/grid/14_11.png new file mode 100644 index 0000000..3c2e0cc Binary files /dev/null and b/tools/lpc_extract/grid/14_11.png differ diff --git a/tools/lpc_extract/grid/14_12.png b/tools/lpc_extract/grid/14_12.png new file mode 100644 index 0000000..98988c3 Binary files /dev/null and b/tools/lpc_extract/grid/14_12.png differ diff --git a/tools/lpc_extract/grid/14_13.png b/tools/lpc_extract/grid/14_13.png new file mode 100644 index 0000000..6d9cb85 Binary files /dev/null and b/tools/lpc_extract/grid/14_13.png differ diff --git a/tools/lpc_extract/grid/14_14.png b/tools/lpc_extract/grid/14_14.png new file mode 100644 index 0000000..b22507e Binary files /dev/null and b/tools/lpc_extract/grid/14_14.png differ diff --git a/tools/lpc_extract/grid/14_15.png b/tools/lpc_extract/grid/14_15.png new file mode 100644 index 0000000..4f5f054 Binary files /dev/null and b/tools/lpc_extract/grid/14_15.png differ diff --git a/tools/lpc_extract/grid/14_16.png b/tools/lpc_extract/grid/14_16.png new file mode 100644 index 0000000..4ad7f12 Binary files /dev/null and b/tools/lpc_extract/grid/14_16.png differ diff --git a/tools/lpc_extract/grid/14_17.png b/tools/lpc_extract/grid/14_17.png new file mode 100644 index 0000000..a27d5dd Binary files /dev/null and b/tools/lpc_extract/grid/14_17.png differ diff --git a/tools/lpc_extract/grid/14_18.png b/tools/lpc_extract/grid/14_18.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_18.png differ diff --git a/tools/lpc_extract/grid/14_19.png b/tools/lpc_extract/grid/14_19.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_19.png differ diff --git a/tools/lpc_extract/grid/14_2.png b/tools/lpc_extract/grid/14_2.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_2.png differ diff --git a/tools/lpc_extract/grid/14_20.png b/tools/lpc_extract/grid/14_20.png new file mode 100644 index 0000000..1dfaeb1 Binary files /dev/null and b/tools/lpc_extract/grid/14_20.png differ diff --git a/tools/lpc_extract/grid/14_21.png b/tools/lpc_extract/grid/14_21.png new file mode 100644 index 0000000..6e2f736 Binary files /dev/null and b/tools/lpc_extract/grid/14_21.png differ diff --git a/tools/lpc_extract/grid/14_22.png b/tools/lpc_extract/grid/14_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_22.png differ diff --git a/tools/lpc_extract/grid/14_23.png b/tools/lpc_extract/grid/14_23.png new file mode 100644 index 0000000..8fbff05 Binary files /dev/null and b/tools/lpc_extract/grid/14_23.png differ diff --git a/tools/lpc_extract/grid/14_24.png b/tools/lpc_extract/grid/14_24.png new file mode 100644 index 0000000..f488ce1 Binary files /dev/null and b/tools/lpc_extract/grid/14_24.png differ diff --git a/tools/lpc_extract/grid/14_25.png b/tools/lpc_extract/grid/14_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_25.png differ diff --git a/tools/lpc_extract/grid/14_3.png b/tools/lpc_extract/grid/14_3.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_3.png differ diff --git a/tools/lpc_extract/grid/14_4.png b/tools/lpc_extract/grid/14_4.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_4.png differ diff --git a/tools/lpc_extract/grid/14_5.png b/tools/lpc_extract/grid/14_5.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_5.png differ diff --git a/tools/lpc_extract/grid/14_6.png b/tools/lpc_extract/grid/14_6.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_6.png differ diff --git a/tools/lpc_extract/grid/14_7.png b/tools/lpc_extract/grid/14_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_7.png differ diff --git a/tools/lpc_extract/grid/14_8.png b/tools/lpc_extract/grid/14_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_8.png differ diff --git a/tools/lpc_extract/grid/14_9.png b/tools/lpc_extract/grid/14_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/14_9.png differ diff --git a/tools/lpc_extract/grid/15_0.png b/tools/lpc_extract/grid/15_0.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_0.png differ diff --git a/tools/lpc_extract/grid/15_1.png b/tools/lpc_extract/grid/15_1.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_1.png differ diff --git a/tools/lpc_extract/grid/15_10.png b/tools/lpc_extract/grid/15_10.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_10.png differ diff --git a/tools/lpc_extract/grid/15_11.png b/tools/lpc_extract/grid/15_11.png new file mode 100644 index 0000000..8a35b5c Binary files /dev/null and b/tools/lpc_extract/grid/15_11.png differ diff --git a/tools/lpc_extract/grid/15_12.png b/tools/lpc_extract/grid/15_12.png new file mode 100644 index 0000000..2bb4f74 Binary files /dev/null and b/tools/lpc_extract/grid/15_12.png differ diff --git a/tools/lpc_extract/grid/15_13.png b/tools/lpc_extract/grid/15_13.png new file mode 100644 index 0000000..84127f7 Binary files /dev/null and b/tools/lpc_extract/grid/15_13.png differ diff --git a/tools/lpc_extract/grid/15_14.png b/tools/lpc_extract/grid/15_14.png new file mode 100644 index 0000000..a25f6c9 Binary files /dev/null and b/tools/lpc_extract/grid/15_14.png differ diff --git a/tools/lpc_extract/grid/15_15.png b/tools/lpc_extract/grid/15_15.png new file mode 100644 index 0000000..d6b2b36 Binary files /dev/null and b/tools/lpc_extract/grid/15_15.png differ diff --git a/tools/lpc_extract/grid/15_16.png b/tools/lpc_extract/grid/15_16.png new file mode 100644 index 0000000..fcc40a8 Binary files /dev/null and b/tools/lpc_extract/grid/15_16.png differ diff --git a/tools/lpc_extract/grid/15_17.png b/tools/lpc_extract/grid/15_17.png new file mode 100644 index 0000000..9c52cc9 Binary files /dev/null and b/tools/lpc_extract/grid/15_17.png differ diff --git a/tools/lpc_extract/grid/15_18.png b/tools/lpc_extract/grid/15_18.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_18.png differ diff --git a/tools/lpc_extract/grid/15_19.png b/tools/lpc_extract/grid/15_19.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_19.png differ diff --git a/tools/lpc_extract/grid/15_2.png b/tools/lpc_extract/grid/15_2.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_2.png differ diff --git a/tools/lpc_extract/grid/15_20.png b/tools/lpc_extract/grid/15_20.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_20.png differ diff --git a/tools/lpc_extract/grid/15_21.png b/tools/lpc_extract/grid/15_21.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_21.png differ diff --git a/tools/lpc_extract/grid/15_22.png b/tools/lpc_extract/grid/15_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_22.png differ diff --git a/tools/lpc_extract/grid/15_23.png b/tools/lpc_extract/grid/15_23.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_23.png differ diff --git a/tools/lpc_extract/grid/15_24.png b/tools/lpc_extract/grid/15_24.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_24.png differ diff --git a/tools/lpc_extract/grid/15_25.png b/tools/lpc_extract/grid/15_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_25.png differ diff --git a/tools/lpc_extract/grid/15_3.png b/tools/lpc_extract/grid/15_3.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_3.png differ diff --git a/tools/lpc_extract/grid/15_4.png b/tools/lpc_extract/grid/15_4.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_4.png differ diff --git a/tools/lpc_extract/grid/15_5.png b/tools/lpc_extract/grid/15_5.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_5.png differ diff --git a/tools/lpc_extract/grid/15_6.png b/tools/lpc_extract/grid/15_6.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_6.png differ diff --git a/tools/lpc_extract/grid/15_7.png b/tools/lpc_extract/grid/15_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_7.png differ diff --git a/tools/lpc_extract/grid/15_8.png b/tools/lpc_extract/grid/15_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_8.png differ diff --git a/tools/lpc_extract/grid/15_9.png b/tools/lpc_extract/grid/15_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/15_9.png differ diff --git a/tools/lpc_extract/grid/1_0.png b/tools/lpc_extract/grid/1_0.png new file mode 100644 index 0000000..4686f6f Binary files /dev/null and b/tools/lpc_extract/grid/1_0.png differ diff --git a/tools/lpc_extract/grid/1_1.png b/tools/lpc_extract/grid/1_1.png new file mode 100644 index 0000000..9404bd1 Binary files /dev/null and b/tools/lpc_extract/grid/1_1.png differ diff --git a/tools/lpc_extract/grid/1_10.png b/tools/lpc_extract/grid/1_10.png new file mode 100644 index 0000000..14d2ebd Binary files /dev/null and b/tools/lpc_extract/grid/1_10.png differ diff --git a/tools/lpc_extract/grid/1_11.png b/tools/lpc_extract/grid/1_11.png new file mode 100644 index 0000000..1ef40dc Binary files /dev/null and b/tools/lpc_extract/grid/1_11.png differ diff --git a/tools/lpc_extract/grid/1_12.png b/tools/lpc_extract/grid/1_12.png new file mode 100644 index 0000000..d7e3f5f Binary files /dev/null and b/tools/lpc_extract/grid/1_12.png differ diff --git a/tools/lpc_extract/grid/1_13.png b/tools/lpc_extract/grid/1_13.png new file mode 100644 index 0000000..6db9c02 Binary files /dev/null and b/tools/lpc_extract/grid/1_13.png differ diff --git a/tools/lpc_extract/grid/1_14.png b/tools/lpc_extract/grid/1_14.png new file mode 100644 index 0000000..33140ac Binary files /dev/null and b/tools/lpc_extract/grid/1_14.png differ diff --git a/tools/lpc_extract/grid/1_15.png b/tools/lpc_extract/grid/1_15.png new file mode 100644 index 0000000..ce17546 Binary files /dev/null and b/tools/lpc_extract/grid/1_15.png differ diff --git a/tools/lpc_extract/grid/1_16.png b/tools/lpc_extract/grid/1_16.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/1_16.png differ diff --git a/tools/lpc_extract/grid/1_17.png b/tools/lpc_extract/grid/1_17.png new file mode 100644 index 0000000..8f14f93 Binary files /dev/null and b/tools/lpc_extract/grid/1_17.png differ diff --git a/tools/lpc_extract/grid/1_18.png b/tools/lpc_extract/grid/1_18.png new file mode 100644 index 0000000..a09b52f Binary files /dev/null and b/tools/lpc_extract/grid/1_18.png differ diff --git a/tools/lpc_extract/grid/1_19.png b/tools/lpc_extract/grid/1_19.png new file mode 100644 index 0000000..c24aa5f Binary files /dev/null and b/tools/lpc_extract/grid/1_19.png differ diff --git a/tools/lpc_extract/grid/1_2.png b/tools/lpc_extract/grid/1_2.png new file mode 100644 index 0000000..fc9bd04 Binary files /dev/null and b/tools/lpc_extract/grid/1_2.png differ diff --git a/tools/lpc_extract/grid/1_20.png b/tools/lpc_extract/grid/1_20.png new file mode 100644 index 0000000..2c20532 Binary files /dev/null and b/tools/lpc_extract/grid/1_20.png differ diff --git a/tools/lpc_extract/grid/1_21.png b/tools/lpc_extract/grid/1_21.png new file mode 100644 index 0000000..1ef40dc Binary files /dev/null and b/tools/lpc_extract/grid/1_21.png differ diff --git a/tools/lpc_extract/grid/1_22.png b/tools/lpc_extract/grid/1_22.png new file mode 100644 index 0000000..1921db7 Binary files /dev/null and b/tools/lpc_extract/grid/1_22.png differ diff --git a/tools/lpc_extract/grid/1_23.png b/tools/lpc_extract/grid/1_23.png new file mode 100644 index 0000000..cac6771 Binary files /dev/null and b/tools/lpc_extract/grid/1_23.png differ diff --git a/tools/lpc_extract/grid/1_24.png b/tools/lpc_extract/grid/1_24.png new file mode 100644 index 0000000..03e4248 Binary files /dev/null and b/tools/lpc_extract/grid/1_24.png differ diff --git a/tools/lpc_extract/grid/1_25.png b/tools/lpc_extract/grid/1_25.png new file mode 100644 index 0000000..1a059e8 Binary files /dev/null and b/tools/lpc_extract/grid/1_25.png differ diff --git a/tools/lpc_extract/grid/1_3.png b/tools/lpc_extract/grid/1_3.png new file mode 100644 index 0000000..a499c93 Binary files /dev/null and b/tools/lpc_extract/grid/1_3.png differ diff --git a/tools/lpc_extract/grid/1_4.png b/tools/lpc_extract/grid/1_4.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/1_4.png differ diff --git a/tools/lpc_extract/grid/1_5.png b/tools/lpc_extract/grid/1_5.png new file mode 100644 index 0000000..9e014fc Binary files /dev/null and b/tools/lpc_extract/grid/1_5.png differ diff --git a/tools/lpc_extract/grid/1_6.png b/tools/lpc_extract/grid/1_6.png new file mode 100644 index 0000000..97c0e06 Binary files /dev/null and b/tools/lpc_extract/grid/1_6.png differ diff --git a/tools/lpc_extract/grid/1_7.png b/tools/lpc_extract/grid/1_7.png new file mode 100644 index 0000000..6dfcd47 Binary files /dev/null and b/tools/lpc_extract/grid/1_7.png differ diff --git a/tools/lpc_extract/grid/1_8.png b/tools/lpc_extract/grid/1_8.png new file mode 100644 index 0000000..43baa13 Binary files /dev/null and b/tools/lpc_extract/grid/1_8.png differ diff --git a/tools/lpc_extract/grid/1_9.png b/tools/lpc_extract/grid/1_9.png new file mode 100644 index 0000000..1812e02 Binary files /dev/null and b/tools/lpc_extract/grid/1_9.png differ diff --git a/tools/lpc_extract/grid/2_0.png b/tools/lpc_extract/grid/2_0.png new file mode 100644 index 0000000..2a4e023 Binary files /dev/null and b/tools/lpc_extract/grid/2_0.png differ diff --git a/tools/lpc_extract/grid/2_1.png b/tools/lpc_extract/grid/2_1.png new file mode 100644 index 0000000..bb6f2d7 Binary files /dev/null and b/tools/lpc_extract/grid/2_1.png differ diff --git a/tools/lpc_extract/grid/2_10.png b/tools/lpc_extract/grid/2_10.png new file mode 100644 index 0000000..d673443 Binary files /dev/null and b/tools/lpc_extract/grid/2_10.png differ diff --git a/tools/lpc_extract/grid/2_11.png b/tools/lpc_extract/grid/2_11.png new file mode 100644 index 0000000..715a283 Binary files /dev/null and b/tools/lpc_extract/grid/2_11.png differ diff --git a/tools/lpc_extract/grid/2_12.png b/tools/lpc_extract/grid/2_12.png new file mode 100644 index 0000000..ee18208 Binary files /dev/null and b/tools/lpc_extract/grid/2_12.png differ diff --git a/tools/lpc_extract/grid/2_13.png b/tools/lpc_extract/grid/2_13.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/2_13.png differ diff --git a/tools/lpc_extract/grid/2_14.png b/tools/lpc_extract/grid/2_14.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/2_14.png differ diff --git a/tools/lpc_extract/grid/2_15.png b/tools/lpc_extract/grid/2_15.png new file mode 100644 index 0000000..bf824ca Binary files /dev/null and b/tools/lpc_extract/grid/2_15.png differ diff --git a/tools/lpc_extract/grid/2_16.png b/tools/lpc_extract/grid/2_16.png new file mode 100644 index 0000000..b1102d5 Binary files /dev/null and b/tools/lpc_extract/grid/2_16.png differ diff --git a/tools/lpc_extract/grid/2_17.png b/tools/lpc_extract/grid/2_17.png new file mode 100644 index 0000000..608868e Binary files /dev/null and b/tools/lpc_extract/grid/2_17.png differ diff --git a/tools/lpc_extract/grid/2_18.png b/tools/lpc_extract/grid/2_18.png new file mode 100644 index 0000000..82e813b Binary files /dev/null and b/tools/lpc_extract/grid/2_18.png differ diff --git a/tools/lpc_extract/grid/2_19.png b/tools/lpc_extract/grid/2_19.png new file mode 100644 index 0000000..0ba21d7 Binary files /dev/null and b/tools/lpc_extract/grid/2_19.png differ diff --git a/tools/lpc_extract/grid/2_2.png b/tools/lpc_extract/grid/2_2.png new file mode 100644 index 0000000..664f544 Binary files /dev/null and b/tools/lpc_extract/grid/2_2.png differ diff --git a/tools/lpc_extract/grid/2_20.png b/tools/lpc_extract/grid/2_20.png new file mode 100644 index 0000000..a8edfa9 Binary files /dev/null and b/tools/lpc_extract/grid/2_20.png differ diff --git a/tools/lpc_extract/grid/2_21.png b/tools/lpc_extract/grid/2_21.png new file mode 100644 index 0000000..2aa85a4 Binary files /dev/null and b/tools/lpc_extract/grid/2_21.png differ diff --git a/tools/lpc_extract/grid/2_22.png b/tools/lpc_extract/grid/2_22.png new file mode 100644 index 0000000..78c2107 Binary files /dev/null and b/tools/lpc_extract/grid/2_22.png differ diff --git a/tools/lpc_extract/grid/2_23.png b/tools/lpc_extract/grid/2_23.png new file mode 100644 index 0000000..c037268 Binary files /dev/null and b/tools/lpc_extract/grid/2_23.png differ diff --git a/tools/lpc_extract/grid/2_24.png b/tools/lpc_extract/grid/2_24.png new file mode 100644 index 0000000..0feb854 Binary files /dev/null and b/tools/lpc_extract/grid/2_24.png differ diff --git a/tools/lpc_extract/grid/2_25.png b/tools/lpc_extract/grid/2_25.png new file mode 100644 index 0000000..be122f5 Binary files /dev/null and b/tools/lpc_extract/grid/2_25.png differ diff --git a/tools/lpc_extract/grid/2_3.png b/tools/lpc_extract/grid/2_3.png new file mode 100644 index 0000000..843db69 Binary files /dev/null and b/tools/lpc_extract/grid/2_3.png differ diff --git a/tools/lpc_extract/grid/2_4.png b/tools/lpc_extract/grid/2_4.png new file mode 100644 index 0000000..11b20c5 Binary files /dev/null and b/tools/lpc_extract/grid/2_4.png differ diff --git a/tools/lpc_extract/grid/2_5.png b/tools/lpc_extract/grid/2_5.png new file mode 100644 index 0000000..7d6a57e Binary files /dev/null and b/tools/lpc_extract/grid/2_5.png differ diff --git a/tools/lpc_extract/grid/2_6.png b/tools/lpc_extract/grid/2_6.png new file mode 100644 index 0000000..5729047 Binary files /dev/null and b/tools/lpc_extract/grid/2_6.png differ diff --git a/tools/lpc_extract/grid/2_7.png b/tools/lpc_extract/grid/2_7.png new file mode 100644 index 0000000..f92d5b4 Binary files /dev/null and b/tools/lpc_extract/grid/2_7.png differ diff --git a/tools/lpc_extract/grid/2_8.png b/tools/lpc_extract/grid/2_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/2_8.png differ diff --git a/tools/lpc_extract/grid/2_9.png b/tools/lpc_extract/grid/2_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/2_9.png differ diff --git a/tools/lpc_extract/grid/3_0.png b/tools/lpc_extract/grid/3_0.png new file mode 100644 index 0000000..b2c7a03 Binary files /dev/null and b/tools/lpc_extract/grid/3_0.png differ diff --git a/tools/lpc_extract/grid/3_1.png b/tools/lpc_extract/grid/3_1.png new file mode 100644 index 0000000..e6bd79f Binary files /dev/null and b/tools/lpc_extract/grid/3_1.png differ diff --git a/tools/lpc_extract/grid/3_10.png b/tools/lpc_extract/grid/3_10.png new file mode 100644 index 0000000..cad3f12 Binary files /dev/null and b/tools/lpc_extract/grid/3_10.png differ diff --git a/tools/lpc_extract/grid/3_11.png b/tools/lpc_extract/grid/3_11.png new file mode 100644 index 0000000..7821c38 Binary files /dev/null and b/tools/lpc_extract/grid/3_11.png differ diff --git a/tools/lpc_extract/grid/3_12.png b/tools/lpc_extract/grid/3_12.png new file mode 100644 index 0000000..559296e Binary files /dev/null and b/tools/lpc_extract/grid/3_12.png differ diff --git a/tools/lpc_extract/grid/3_13.png b/tools/lpc_extract/grid/3_13.png new file mode 100644 index 0000000..244eac3 Binary files /dev/null and b/tools/lpc_extract/grid/3_13.png differ diff --git a/tools/lpc_extract/grid/3_14.png b/tools/lpc_extract/grid/3_14.png new file mode 100644 index 0000000..f0dce14 Binary files /dev/null and b/tools/lpc_extract/grid/3_14.png differ diff --git a/tools/lpc_extract/grid/3_15.png b/tools/lpc_extract/grid/3_15.png new file mode 100644 index 0000000..9d737a1 Binary files /dev/null and b/tools/lpc_extract/grid/3_15.png differ diff --git a/tools/lpc_extract/grid/3_16.png b/tools/lpc_extract/grid/3_16.png new file mode 100644 index 0000000..f275650 Binary files /dev/null and b/tools/lpc_extract/grid/3_16.png differ diff --git a/tools/lpc_extract/grid/3_17.png b/tools/lpc_extract/grid/3_17.png new file mode 100644 index 0000000..c6f85d2 Binary files /dev/null and b/tools/lpc_extract/grid/3_17.png differ diff --git a/tools/lpc_extract/grid/3_18.png b/tools/lpc_extract/grid/3_18.png new file mode 100644 index 0000000..abdbd1e Binary files /dev/null and b/tools/lpc_extract/grid/3_18.png differ diff --git a/tools/lpc_extract/grid/3_19.png b/tools/lpc_extract/grid/3_19.png new file mode 100644 index 0000000..79bf5d3 Binary files /dev/null and b/tools/lpc_extract/grid/3_19.png differ diff --git a/tools/lpc_extract/grid/3_2.png b/tools/lpc_extract/grid/3_2.png new file mode 100644 index 0000000..2f7a2ab Binary files /dev/null and b/tools/lpc_extract/grid/3_2.png differ diff --git a/tools/lpc_extract/grid/3_20.png b/tools/lpc_extract/grid/3_20.png new file mode 100644 index 0000000..b25c563 Binary files /dev/null and b/tools/lpc_extract/grid/3_20.png differ diff --git a/tools/lpc_extract/grid/3_21.png b/tools/lpc_extract/grid/3_21.png new file mode 100644 index 0000000..2456b2b Binary files /dev/null and b/tools/lpc_extract/grid/3_21.png differ diff --git a/tools/lpc_extract/grid/3_22.png b/tools/lpc_extract/grid/3_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/3_22.png differ diff --git a/tools/lpc_extract/grid/3_23.png b/tools/lpc_extract/grid/3_23.png new file mode 100644 index 0000000..d67b7d4 Binary files /dev/null and b/tools/lpc_extract/grid/3_23.png differ diff --git a/tools/lpc_extract/grid/3_24.png b/tools/lpc_extract/grid/3_24.png new file mode 100644 index 0000000..96aaaa7 Binary files /dev/null and b/tools/lpc_extract/grid/3_24.png differ diff --git a/tools/lpc_extract/grid/3_25.png b/tools/lpc_extract/grid/3_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/3_25.png differ diff --git a/tools/lpc_extract/grid/3_3.png b/tools/lpc_extract/grid/3_3.png new file mode 100644 index 0000000..b729bb8 Binary files /dev/null and b/tools/lpc_extract/grid/3_3.png differ diff --git a/tools/lpc_extract/grid/3_4.png b/tools/lpc_extract/grid/3_4.png new file mode 100644 index 0000000..bf4fede Binary files /dev/null and b/tools/lpc_extract/grid/3_4.png differ diff --git a/tools/lpc_extract/grid/3_5.png b/tools/lpc_extract/grid/3_5.png new file mode 100644 index 0000000..ccc8c36 Binary files /dev/null and b/tools/lpc_extract/grid/3_5.png differ diff --git a/tools/lpc_extract/grid/3_6.png b/tools/lpc_extract/grid/3_6.png new file mode 100644 index 0000000..35ef55a Binary files /dev/null and b/tools/lpc_extract/grid/3_6.png differ diff --git a/tools/lpc_extract/grid/3_7.png b/tools/lpc_extract/grid/3_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/3_7.png differ diff --git a/tools/lpc_extract/grid/3_8.png b/tools/lpc_extract/grid/3_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/3_8.png differ diff --git a/tools/lpc_extract/grid/3_9.png b/tools/lpc_extract/grid/3_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/3_9.png differ diff --git a/tools/lpc_extract/grid/4_0.png b/tools/lpc_extract/grid/4_0.png new file mode 100644 index 0000000..771816c Binary files /dev/null and b/tools/lpc_extract/grid/4_0.png differ diff --git a/tools/lpc_extract/grid/4_1.png b/tools/lpc_extract/grid/4_1.png new file mode 100644 index 0000000..6e687f1 Binary files /dev/null and b/tools/lpc_extract/grid/4_1.png differ diff --git a/tools/lpc_extract/grid/4_10.png b/tools/lpc_extract/grid/4_10.png new file mode 100644 index 0000000..093d37d Binary files /dev/null and b/tools/lpc_extract/grid/4_10.png differ diff --git a/tools/lpc_extract/grid/4_11.png b/tools/lpc_extract/grid/4_11.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_11.png differ diff --git a/tools/lpc_extract/grid/4_12.png b/tools/lpc_extract/grid/4_12.png new file mode 100644 index 0000000..d9ba3be Binary files /dev/null and b/tools/lpc_extract/grid/4_12.png differ diff --git a/tools/lpc_extract/grid/4_13.png b/tools/lpc_extract/grid/4_13.png new file mode 100644 index 0000000..a9eb04d Binary files /dev/null and b/tools/lpc_extract/grid/4_13.png differ diff --git a/tools/lpc_extract/grid/4_14.png b/tools/lpc_extract/grid/4_14.png new file mode 100644 index 0000000..6ebde00 Binary files /dev/null and b/tools/lpc_extract/grid/4_14.png differ diff --git a/tools/lpc_extract/grid/4_15.png b/tools/lpc_extract/grid/4_15.png new file mode 100644 index 0000000..6044583 Binary files /dev/null and b/tools/lpc_extract/grid/4_15.png differ diff --git a/tools/lpc_extract/grid/4_16.png b/tools/lpc_extract/grid/4_16.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_16.png differ diff --git a/tools/lpc_extract/grid/4_17.png b/tools/lpc_extract/grid/4_17.png new file mode 100644 index 0000000..25e6c6e Binary files /dev/null and b/tools/lpc_extract/grid/4_17.png differ diff --git a/tools/lpc_extract/grid/4_18.png b/tools/lpc_extract/grid/4_18.png new file mode 100644 index 0000000..5ad62ba Binary files /dev/null and b/tools/lpc_extract/grid/4_18.png differ diff --git a/tools/lpc_extract/grid/4_19.png b/tools/lpc_extract/grid/4_19.png new file mode 100644 index 0000000..bfad1a4 Binary files /dev/null and b/tools/lpc_extract/grid/4_19.png differ diff --git a/tools/lpc_extract/grid/4_2.png b/tools/lpc_extract/grid/4_2.png new file mode 100644 index 0000000..fb6d612 Binary files /dev/null and b/tools/lpc_extract/grid/4_2.png differ diff --git a/tools/lpc_extract/grid/4_20.png b/tools/lpc_extract/grid/4_20.png new file mode 100644 index 0000000..bb97290 Binary files /dev/null and b/tools/lpc_extract/grid/4_20.png differ diff --git a/tools/lpc_extract/grid/4_21.png b/tools/lpc_extract/grid/4_21.png new file mode 100644 index 0000000..48bfb37 Binary files /dev/null and b/tools/lpc_extract/grid/4_21.png differ diff --git a/tools/lpc_extract/grid/4_22.png b/tools/lpc_extract/grid/4_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_22.png differ diff --git a/tools/lpc_extract/grid/4_23.png b/tools/lpc_extract/grid/4_23.png new file mode 100644 index 0000000..e061de4 Binary files /dev/null and b/tools/lpc_extract/grid/4_23.png differ diff --git a/tools/lpc_extract/grid/4_24.png b/tools/lpc_extract/grid/4_24.png new file mode 100644 index 0000000..31e0a51 Binary files /dev/null and b/tools/lpc_extract/grid/4_24.png differ diff --git a/tools/lpc_extract/grid/4_25.png b/tools/lpc_extract/grid/4_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_25.png differ diff --git a/tools/lpc_extract/grid/4_3.png b/tools/lpc_extract/grid/4_3.png new file mode 100644 index 0000000..11ef425 Binary files /dev/null and b/tools/lpc_extract/grid/4_3.png differ diff --git a/tools/lpc_extract/grid/4_4.png b/tools/lpc_extract/grid/4_4.png new file mode 100644 index 0000000..4511c05 Binary files /dev/null and b/tools/lpc_extract/grid/4_4.png differ diff --git a/tools/lpc_extract/grid/4_5.png b/tools/lpc_extract/grid/4_5.png new file mode 100644 index 0000000..8e345e5 Binary files /dev/null and b/tools/lpc_extract/grid/4_5.png differ diff --git a/tools/lpc_extract/grid/4_6.png b/tools/lpc_extract/grid/4_6.png new file mode 100644 index 0000000..75f6259 Binary files /dev/null and b/tools/lpc_extract/grid/4_6.png differ diff --git a/tools/lpc_extract/grid/4_7.png b/tools/lpc_extract/grid/4_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_7.png differ diff --git a/tools/lpc_extract/grid/4_8.png b/tools/lpc_extract/grid/4_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_8.png differ diff --git a/tools/lpc_extract/grid/4_9.png b/tools/lpc_extract/grid/4_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/4_9.png differ diff --git a/tools/lpc_extract/grid/5_0.png b/tools/lpc_extract/grid/5_0.png new file mode 100644 index 0000000..da361c1 Binary files /dev/null and b/tools/lpc_extract/grid/5_0.png differ diff --git a/tools/lpc_extract/grid/5_1.png b/tools/lpc_extract/grid/5_1.png new file mode 100644 index 0000000..bbd0242 Binary files /dev/null and b/tools/lpc_extract/grid/5_1.png differ diff --git a/tools/lpc_extract/grid/5_10.png b/tools/lpc_extract/grid/5_10.png new file mode 100644 index 0000000..9f60f68 Binary files /dev/null and b/tools/lpc_extract/grid/5_10.png differ diff --git a/tools/lpc_extract/grid/5_11.png b/tools/lpc_extract/grid/5_11.png new file mode 100644 index 0000000..a201dd2 Binary files /dev/null and b/tools/lpc_extract/grid/5_11.png differ diff --git a/tools/lpc_extract/grid/5_12.png b/tools/lpc_extract/grid/5_12.png new file mode 100644 index 0000000..1c590b5 Binary files /dev/null and b/tools/lpc_extract/grid/5_12.png differ diff --git a/tools/lpc_extract/grid/5_13.png b/tools/lpc_extract/grid/5_13.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/5_13.png differ diff --git a/tools/lpc_extract/grid/5_14.png b/tools/lpc_extract/grid/5_14.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/5_14.png differ diff --git a/tools/lpc_extract/grid/5_15.png b/tools/lpc_extract/grid/5_15.png new file mode 100644 index 0000000..91d7d3f Binary files /dev/null and b/tools/lpc_extract/grid/5_15.png differ diff --git a/tools/lpc_extract/grid/5_16.png b/tools/lpc_extract/grid/5_16.png new file mode 100644 index 0000000..de359f6 Binary files /dev/null and b/tools/lpc_extract/grid/5_16.png differ diff --git a/tools/lpc_extract/grid/5_17.png b/tools/lpc_extract/grid/5_17.png new file mode 100644 index 0000000..82bd446 Binary files /dev/null and b/tools/lpc_extract/grid/5_17.png differ diff --git a/tools/lpc_extract/grid/5_18.png b/tools/lpc_extract/grid/5_18.png new file mode 100644 index 0000000..8d5c229 Binary files /dev/null and b/tools/lpc_extract/grid/5_18.png differ diff --git a/tools/lpc_extract/grid/5_19.png b/tools/lpc_extract/grid/5_19.png new file mode 100644 index 0000000..ff7938e Binary files /dev/null and b/tools/lpc_extract/grid/5_19.png differ diff --git a/tools/lpc_extract/grid/5_2.png b/tools/lpc_extract/grid/5_2.png new file mode 100644 index 0000000..5badc6f Binary files /dev/null and b/tools/lpc_extract/grid/5_2.png differ diff --git a/tools/lpc_extract/grid/5_20.png b/tools/lpc_extract/grid/5_20.png new file mode 100644 index 0000000..022877c Binary files /dev/null and b/tools/lpc_extract/grid/5_20.png differ diff --git a/tools/lpc_extract/grid/5_21.png b/tools/lpc_extract/grid/5_21.png new file mode 100644 index 0000000..47f649b Binary files /dev/null and b/tools/lpc_extract/grid/5_21.png differ diff --git a/tools/lpc_extract/grid/5_22.png b/tools/lpc_extract/grid/5_22.png new file mode 100644 index 0000000..6a63bea Binary files /dev/null and b/tools/lpc_extract/grid/5_22.png differ diff --git a/tools/lpc_extract/grid/5_23.png b/tools/lpc_extract/grid/5_23.png new file mode 100644 index 0000000..dbfa943 Binary files /dev/null and b/tools/lpc_extract/grid/5_23.png differ diff --git a/tools/lpc_extract/grid/5_24.png b/tools/lpc_extract/grid/5_24.png new file mode 100644 index 0000000..9edf332 Binary files /dev/null and b/tools/lpc_extract/grid/5_24.png differ diff --git a/tools/lpc_extract/grid/5_25.png b/tools/lpc_extract/grid/5_25.png new file mode 100644 index 0000000..ec34941 Binary files /dev/null and b/tools/lpc_extract/grid/5_25.png differ diff --git a/tools/lpc_extract/grid/5_3.png b/tools/lpc_extract/grid/5_3.png new file mode 100644 index 0000000..330c7de Binary files /dev/null and b/tools/lpc_extract/grid/5_3.png differ diff --git a/tools/lpc_extract/grid/5_4.png b/tools/lpc_extract/grid/5_4.png new file mode 100644 index 0000000..6b399c7 Binary files /dev/null and b/tools/lpc_extract/grid/5_4.png differ diff --git a/tools/lpc_extract/grid/5_5.png b/tools/lpc_extract/grid/5_5.png new file mode 100644 index 0000000..2f14b8e Binary files /dev/null and b/tools/lpc_extract/grid/5_5.png differ diff --git a/tools/lpc_extract/grid/5_6.png b/tools/lpc_extract/grid/5_6.png new file mode 100644 index 0000000..6f96a99 Binary files /dev/null and b/tools/lpc_extract/grid/5_6.png differ diff --git a/tools/lpc_extract/grid/5_7.png b/tools/lpc_extract/grid/5_7.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/5_7.png differ diff --git a/tools/lpc_extract/grid/5_8.png b/tools/lpc_extract/grid/5_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/5_8.png differ diff --git a/tools/lpc_extract/grid/5_9.png b/tools/lpc_extract/grid/5_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/5_9.png differ diff --git a/tools/lpc_extract/grid/6_0.png b/tools/lpc_extract/grid/6_0.png new file mode 100644 index 0000000..9646000 Binary files /dev/null and b/tools/lpc_extract/grid/6_0.png differ diff --git a/tools/lpc_extract/grid/6_1.png b/tools/lpc_extract/grid/6_1.png new file mode 100644 index 0000000..e7f9cb3 Binary files /dev/null and b/tools/lpc_extract/grid/6_1.png differ diff --git a/tools/lpc_extract/grid/6_10.png b/tools/lpc_extract/grid/6_10.png new file mode 100644 index 0000000..3d2e34e Binary files /dev/null and b/tools/lpc_extract/grid/6_10.png differ diff --git a/tools/lpc_extract/grid/6_11.png b/tools/lpc_extract/grid/6_11.png new file mode 100644 index 0000000..a16c0bd Binary files /dev/null and b/tools/lpc_extract/grid/6_11.png differ diff --git a/tools/lpc_extract/grid/6_12.png b/tools/lpc_extract/grid/6_12.png new file mode 100644 index 0000000..76fe46d Binary files /dev/null and b/tools/lpc_extract/grid/6_12.png differ diff --git a/tools/lpc_extract/grid/6_13.png b/tools/lpc_extract/grid/6_13.png new file mode 100644 index 0000000..8c0c3dc Binary files /dev/null and b/tools/lpc_extract/grid/6_13.png differ diff --git a/tools/lpc_extract/grid/6_14.png b/tools/lpc_extract/grid/6_14.png new file mode 100644 index 0000000..deaacdb Binary files /dev/null and b/tools/lpc_extract/grid/6_14.png differ diff --git a/tools/lpc_extract/grid/6_15.png b/tools/lpc_extract/grid/6_15.png new file mode 100644 index 0000000..9e659d5 Binary files /dev/null and b/tools/lpc_extract/grid/6_15.png differ diff --git a/tools/lpc_extract/grid/6_16.png b/tools/lpc_extract/grid/6_16.png new file mode 100644 index 0000000..1a6cba2 Binary files /dev/null and b/tools/lpc_extract/grid/6_16.png differ diff --git a/tools/lpc_extract/grid/6_17.png b/tools/lpc_extract/grid/6_17.png new file mode 100644 index 0000000..f3ebe3d Binary files /dev/null and b/tools/lpc_extract/grid/6_17.png differ diff --git a/tools/lpc_extract/grid/6_18.png b/tools/lpc_extract/grid/6_18.png new file mode 100644 index 0000000..3839da4 Binary files /dev/null and b/tools/lpc_extract/grid/6_18.png differ diff --git a/tools/lpc_extract/grid/6_19.png b/tools/lpc_extract/grid/6_19.png new file mode 100644 index 0000000..4e36ae8 Binary files /dev/null and b/tools/lpc_extract/grid/6_19.png differ diff --git a/tools/lpc_extract/grid/6_2.png b/tools/lpc_extract/grid/6_2.png new file mode 100644 index 0000000..faf34cf Binary files /dev/null and b/tools/lpc_extract/grid/6_2.png differ diff --git a/tools/lpc_extract/grid/6_20.png b/tools/lpc_extract/grid/6_20.png new file mode 100644 index 0000000..2bb43fc Binary files /dev/null and b/tools/lpc_extract/grid/6_20.png differ diff --git a/tools/lpc_extract/grid/6_21.png b/tools/lpc_extract/grid/6_21.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/6_21.png differ diff --git a/tools/lpc_extract/grid/6_22.png b/tools/lpc_extract/grid/6_22.png new file mode 100644 index 0000000..e245b7e Binary files /dev/null and b/tools/lpc_extract/grid/6_22.png differ diff --git a/tools/lpc_extract/grid/6_23.png b/tools/lpc_extract/grid/6_23.png new file mode 100644 index 0000000..58109e0 Binary files /dev/null and b/tools/lpc_extract/grid/6_23.png differ diff --git a/tools/lpc_extract/grid/6_24.png b/tools/lpc_extract/grid/6_24.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/6_24.png differ diff --git a/tools/lpc_extract/grid/6_25.png b/tools/lpc_extract/grid/6_25.png new file mode 100644 index 0000000..145e4c9 Binary files /dev/null and b/tools/lpc_extract/grid/6_25.png differ diff --git a/tools/lpc_extract/grid/6_3.png b/tools/lpc_extract/grid/6_3.png new file mode 100644 index 0000000..6f468d8 Binary files /dev/null and b/tools/lpc_extract/grid/6_3.png differ diff --git a/tools/lpc_extract/grid/6_4.png b/tools/lpc_extract/grid/6_4.png new file mode 100644 index 0000000..f8a0f68 Binary files /dev/null and b/tools/lpc_extract/grid/6_4.png differ diff --git a/tools/lpc_extract/grid/6_5.png b/tools/lpc_extract/grid/6_5.png new file mode 100644 index 0000000..eee4eca Binary files /dev/null and b/tools/lpc_extract/grid/6_5.png differ diff --git a/tools/lpc_extract/grid/6_6.png b/tools/lpc_extract/grid/6_6.png new file mode 100644 index 0000000..f051176 Binary files /dev/null and b/tools/lpc_extract/grid/6_6.png differ diff --git a/tools/lpc_extract/grid/6_7.png b/tools/lpc_extract/grid/6_7.png new file mode 100644 index 0000000..9ea9031 Binary files /dev/null and b/tools/lpc_extract/grid/6_7.png differ diff --git a/tools/lpc_extract/grid/6_8.png b/tools/lpc_extract/grid/6_8.png new file mode 100644 index 0000000..680a117 Binary files /dev/null and b/tools/lpc_extract/grid/6_8.png differ diff --git a/tools/lpc_extract/grid/6_9.png b/tools/lpc_extract/grid/6_9.png new file mode 100644 index 0000000..60114b3 Binary files /dev/null and b/tools/lpc_extract/grid/6_9.png differ diff --git a/tools/lpc_extract/grid/7_0.png b/tools/lpc_extract/grid/7_0.png new file mode 100644 index 0000000..7f7ad2a Binary files /dev/null and b/tools/lpc_extract/grid/7_0.png differ diff --git a/tools/lpc_extract/grid/7_1.png b/tools/lpc_extract/grid/7_1.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/7_1.png differ diff --git a/tools/lpc_extract/grid/7_10.png b/tools/lpc_extract/grid/7_10.png new file mode 100644 index 0000000..b19253a Binary files /dev/null and b/tools/lpc_extract/grid/7_10.png differ diff --git a/tools/lpc_extract/grid/7_11.png b/tools/lpc_extract/grid/7_11.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/7_11.png differ diff --git a/tools/lpc_extract/grid/7_12.png b/tools/lpc_extract/grid/7_12.png new file mode 100644 index 0000000..395141e Binary files /dev/null and b/tools/lpc_extract/grid/7_12.png differ diff --git a/tools/lpc_extract/grid/7_13.png b/tools/lpc_extract/grid/7_13.png new file mode 100644 index 0000000..8f142c7 Binary files /dev/null and b/tools/lpc_extract/grid/7_13.png differ diff --git a/tools/lpc_extract/grid/7_14.png b/tools/lpc_extract/grid/7_14.png new file mode 100644 index 0000000..3228ad7 Binary files /dev/null and b/tools/lpc_extract/grid/7_14.png differ diff --git a/tools/lpc_extract/grid/7_15.png b/tools/lpc_extract/grid/7_15.png new file mode 100644 index 0000000..d5f44ea Binary files /dev/null and b/tools/lpc_extract/grid/7_15.png differ diff --git a/tools/lpc_extract/grid/7_16.png b/tools/lpc_extract/grid/7_16.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/7_16.png differ diff --git a/tools/lpc_extract/grid/7_17.png b/tools/lpc_extract/grid/7_17.png new file mode 100644 index 0000000..72a653c Binary files /dev/null and b/tools/lpc_extract/grid/7_17.png differ diff --git a/tools/lpc_extract/grid/7_18.png b/tools/lpc_extract/grid/7_18.png new file mode 100644 index 0000000..f8fa329 Binary files /dev/null and b/tools/lpc_extract/grid/7_18.png differ diff --git a/tools/lpc_extract/grid/7_19.png b/tools/lpc_extract/grid/7_19.png new file mode 100644 index 0000000..205d975 Binary files /dev/null and b/tools/lpc_extract/grid/7_19.png differ diff --git a/tools/lpc_extract/grid/7_2.png b/tools/lpc_extract/grid/7_2.png new file mode 100644 index 0000000..19355c5 Binary files /dev/null and b/tools/lpc_extract/grid/7_2.png differ diff --git a/tools/lpc_extract/grid/7_20.png b/tools/lpc_extract/grid/7_20.png new file mode 100644 index 0000000..a7584e8 Binary files /dev/null and b/tools/lpc_extract/grid/7_20.png differ diff --git a/tools/lpc_extract/grid/7_21.png b/tools/lpc_extract/grid/7_21.png new file mode 100644 index 0000000..d1fdbdd Binary files /dev/null and b/tools/lpc_extract/grid/7_21.png differ diff --git a/tools/lpc_extract/grid/7_22.png b/tools/lpc_extract/grid/7_22.png new file mode 100644 index 0000000..0b9a965 Binary files /dev/null and b/tools/lpc_extract/grid/7_22.png differ diff --git a/tools/lpc_extract/grid/7_23.png b/tools/lpc_extract/grid/7_23.png new file mode 100644 index 0000000..3f07aca Binary files /dev/null and b/tools/lpc_extract/grid/7_23.png differ diff --git a/tools/lpc_extract/grid/7_24.png b/tools/lpc_extract/grid/7_24.png new file mode 100644 index 0000000..fc92bfb Binary files /dev/null and b/tools/lpc_extract/grid/7_24.png differ diff --git a/tools/lpc_extract/grid/7_25.png b/tools/lpc_extract/grid/7_25.png new file mode 100644 index 0000000..e47be22 Binary files /dev/null and b/tools/lpc_extract/grid/7_25.png differ diff --git a/tools/lpc_extract/grid/7_3.png b/tools/lpc_extract/grid/7_3.png new file mode 100644 index 0000000..1d53fcd Binary files /dev/null and b/tools/lpc_extract/grid/7_3.png differ diff --git a/tools/lpc_extract/grid/7_4.png b/tools/lpc_extract/grid/7_4.png new file mode 100644 index 0000000..2f2f75d Binary files /dev/null and b/tools/lpc_extract/grid/7_4.png differ diff --git a/tools/lpc_extract/grid/7_5.png b/tools/lpc_extract/grid/7_5.png new file mode 100644 index 0000000..2d3564b Binary files /dev/null and b/tools/lpc_extract/grid/7_5.png differ diff --git a/tools/lpc_extract/grid/7_6.png b/tools/lpc_extract/grid/7_6.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/7_6.png differ diff --git a/tools/lpc_extract/grid/7_7.png b/tools/lpc_extract/grid/7_7.png new file mode 100644 index 0000000..5e8b75b Binary files /dev/null and b/tools/lpc_extract/grid/7_7.png differ diff --git a/tools/lpc_extract/grid/7_8.png b/tools/lpc_extract/grid/7_8.png new file mode 100644 index 0000000..bdd10ca Binary files /dev/null and b/tools/lpc_extract/grid/7_8.png differ diff --git a/tools/lpc_extract/grid/7_9.png b/tools/lpc_extract/grid/7_9.png new file mode 100644 index 0000000..867db0d Binary files /dev/null and b/tools/lpc_extract/grid/7_9.png differ diff --git a/tools/lpc_extract/grid/8_0.png b/tools/lpc_extract/grid/8_0.png new file mode 100644 index 0000000..3a3d8c6 Binary files /dev/null and b/tools/lpc_extract/grid/8_0.png differ diff --git a/tools/lpc_extract/grid/8_1.png b/tools/lpc_extract/grid/8_1.png new file mode 100644 index 0000000..d670c6b Binary files /dev/null and b/tools/lpc_extract/grid/8_1.png differ diff --git a/tools/lpc_extract/grid/8_10.png b/tools/lpc_extract/grid/8_10.png new file mode 100644 index 0000000..08f7c33 Binary files /dev/null and b/tools/lpc_extract/grid/8_10.png differ diff --git a/tools/lpc_extract/grid/8_11.png b/tools/lpc_extract/grid/8_11.png new file mode 100644 index 0000000..0f34a12 Binary files /dev/null and b/tools/lpc_extract/grid/8_11.png differ diff --git a/tools/lpc_extract/grid/8_12.png b/tools/lpc_extract/grid/8_12.png new file mode 100644 index 0000000..4de1959 Binary files /dev/null and b/tools/lpc_extract/grid/8_12.png differ diff --git a/tools/lpc_extract/grid/8_13.png b/tools/lpc_extract/grid/8_13.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_13.png differ diff --git a/tools/lpc_extract/grid/8_14.png b/tools/lpc_extract/grid/8_14.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_14.png differ diff --git a/tools/lpc_extract/grid/8_15.png b/tools/lpc_extract/grid/8_15.png new file mode 100644 index 0000000..f19a347 Binary files /dev/null and b/tools/lpc_extract/grid/8_15.png differ diff --git a/tools/lpc_extract/grid/8_16.png b/tools/lpc_extract/grid/8_16.png new file mode 100644 index 0000000..5337622 Binary files /dev/null and b/tools/lpc_extract/grid/8_16.png differ diff --git a/tools/lpc_extract/grid/8_17.png b/tools/lpc_extract/grid/8_17.png new file mode 100644 index 0000000..f6b6fd5 Binary files /dev/null and b/tools/lpc_extract/grid/8_17.png differ diff --git a/tools/lpc_extract/grid/8_18.png b/tools/lpc_extract/grid/8_18.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_18.png differ diff --git a/tools/lpc_extract/grid/8_19.png b/tools/lpc_extract/grid/8_19.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_19.png differ diff --git a/tools/lpc_extract/grid/8_2.png b/tools/lpc_extract/grid/8_2.png new file mode 100644 index 0000000..d91bf2f Binary files /dev/null and b/tools/lpc_extract/grid/8_2.png differ diff --git a/tools/lpc_extract/grid/8_20.png b/tools/lpc_extract/grid/8_20.png new file mode 100644 index 0000000..f94db76 Binary files /dev/null and b/tools/lpc_extract/grid/8_20.png differ diff --git a/tools/lpc_extract/grid/8_21.png b/tools/lpc_extract/grid/8_21.png new file mode 100644 index 0000000..5faac7b Binary files /dev/null and b/tools/lpc_extract/grid/8_21.png differ diff --git a/tools/lpc_extract/grid/8_22.png b/tools/lpc_extract/grid/8_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_22.png differ diff --git a/tools/lpc_extract/grid/8_23.png b/tools/lpc_extract/grid/8_23.png new file mode 100644 index 0000000..1eb5987 Binary files /dev/null and b/tools/lpc_extract/grid/8_23.png differ diff --git a/tools/lpc_extract/grid/8_24.png b/tools/lpc_extract/grid/8_24.png new file mode 100644 index 0000000..6cc08b4 Binary files /dev/null and b/tools/lpc_extract/grid/8_24.png differ diff --git a/tools/lpc_extract/grid/8_25.png b/tools/lpc_extract/grid/8_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_25.png differ diff --git a/tools/lpc_extract/grid/8_3.png b/tools/lpc_extract/grid/8_3.png new file mode 100644 index 0000000..997d123 Binary files /dev/null and b/tools/lpc_extract/grid/8_3.png differ diff --git a/tools/lpc_extract/grid/8_4.png b/tools/lpc_extract/grid/8_4.png new file mode 100644 index 0000000..d50b231 Binary files /dev/null and b/tools/lpc_extract/grid/8_4.png differ diff --git a/tools/lpc_extract/grid/8_5.png b/tools/lpc_extract/grid/8_5.png new file mode 100644 index 0000000..a028ab7 Binary files /dev/null and b/tools/lpc_extract/grid/8_5.png differ diff --git a/tools/lpc_extract/grid/8_6.png b/tools/lpc_extract/grid/8_6.png new file mode 100644 index 0000000..d3f24e6 Binary files /dev/null and b/tools/lpc_extract/grid/8_6.png differ diff --git a/tools/lpc_extract/grid/8_7.png b/tools/lpc_extract/grid/8_7.png new file mode 100644 index 0000000..1ffecce Binary files /dev/null and b/tools/lpc_extract/grid/8_7.png differ diff --git a/tools/lpc_extract/grid/8_8.png b/tools/lpc_extract/grid/8_8.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_8.png differ diff --git a/tools/lpc_extract/grid/8_9.png b/tools/lpc_extract/grid/8_9.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/8_9.png differ diff --git a/tools/lpc_extract/grid/9_0.png b/tools/lpc_extract/grid/9_0.png new file mode 100644 index 0000000..7b88082 Binary files /dev/null and b/tools/lpc_extract/grid/9_0.png differ diff --git a/tools/lpc_extract/grid/9_1.png b/tools/lpc_extract/grid/9_1.png new file mode 100644 index 0000000..5ae8cda Binary files /dev/null and b/tools/lpc_extract/grid/9_1.png differ diff --git a/tools/lpc_extract/grid/9_10.png b/tools/lpc_extract/grid/9_10.png new file mode 100644 index 0000000..db77e76 Binary files /dev/null and b/tools/lpc_extract/grid/9_10.png differ diff --git a/tools/lpc_extract/grid/9_11.png b/tools/lpc_extract/grid/9_11.png new file mode 100644 index 0000000..dc52107 Binary files /dev/null and b/tools/lpc_extract/grid/9_11.png differ diff --git a/tools/lpc_extract/grid/9_12.png b/tools/lpc_extract/grid/9_12.png new file mode 100644 index 0000000..6f8189e Binary files /dev/null and b/tools/lpc_extract/grid/9_12.png differ diff --git a/tools/lpc_extract/grid/9_13.png b/tools/lpc_extract/grid/9_13.png new file mode 100644 index 0000000..36c6d87 Binary files /dev/null and b/tools/lpc_extract/grid/9_13.png differ diff --git a/tools/lpc_extract/grid/9_14.png b/tools/lpc_extract/grid/9_14.png new file mode 100644 index 0000000..eac5fa3 Binary files /dev/null and b/tools/lpc_extract/grid/9_14.png differ diff --git a/tools/lpc_extract/grid/9_15.png b/tools/lpc_extract/grid/9_15.png new file mode 100644 index 0000000..e90541b Binary files /dev/null and b/tools/lpc_extract/grid/9_15.png differ diff --git a/tools/lpc_extract/grid/9_16.png b/tools/lpc_extract/grid/9_16.png new file mode 100644 index 0000000..b043206 Binary files /dev/null and b/tools/lpc_extract/grid/9_16.png differ diff --git a/tools/lpc_extract/grid/9_17.png b/tools/lpc_extract/grid/9_17.png new file mode 100644 index 0000000..fc50a9f Binary files /dev/null and b/tools/lpc_extract/grid/9_17.png differ diff --git a/tools/lpc_extract/grid/9_18.png b/tools/lpc_extract/grid/9_18.png new file mode 100644 index 0000000..8f9cbd4 Binary files /dev/null and b/tools/lpc_extract/grid/9_18.png differ diff --git a/tools/lpc_extract/grid/9_19.png b/tools/lpc_extract/grid/9_19.png new file mode 100644 index 0000000..ddd542e Binary files /dev/null and b/tools/lpc_extract/grid/9_19.png differ diff --git a/tools/lpc_extract/grid/9_2.png b/tools/lpc_extract/grid/9_2.png new file mode 100644 index 0000000..99563e9 Binary files /dev/null and b/tools/lpc_extract/grid/9_2.png differ diff --git a/tools/lpc_extract/grid/9_20.png b/tools/lpc_extract/grid/9_20.png new file mode 100644 index 0000000..669b249 Binary files /dev/null and b/tools/lpc_extract/grid/9_20.png differ diff --git a/tools/lpc_extract/grid/9_21.png b/tools/lpc_extract/grid/9_21.png new file mode 100644 index 0000000..fbcce5c Binary files /dev/null and b/tools/lpc_extract/grid/9_21.png differ diff --git a/tools/lpc_extract/grid/9_22.png b/tools/lpc_extract/grid/9_22.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/9_22.png differ diff --git a/tools/lpc_extract/grid/9_23.png b/tools/lpc_extract/grid/9_23.png new file mode 100644 index 0000000..792a90e Binary files /dev/null and b/tools/lpc_extract/grid/9_23.png differ diff --git a/tools/lpc_extract/grid/9_24.png b/tools/lpc_extract/grid/9_24.png new file mode 100644 index 0000000..d630a9a Binary files /dev/null and b/tools/lpc_extract/grid/9_24.png differ diff --git a/tools/lpc_extract/grid/9_25.png b/tools/lpc_extract/grid/9_25.png new file mode 100644 index 0000000..6e3cb09 Binary files /dev/null and b/tools/lpc_extract/grid/9_25.png differ diff --git a/tools/lpc_extract/grid/9_3.png b/tools/lpc_extract/grid/9_3.png new file mode 100644 index 0000000..a113e96 Binary files /dev/null and b/tools/lpc_extract/grid/9_3.png differ diff --git a/tools/lpc_extract/grid/9_4.png b/tools/lpc_extract/grid/9_4.png new file mode 100644 index 0000000..74d7aea Binary files /dev/null and b/tools/lpc_extract/grid/9_4.png differ diff --git a/tools/lpc_extract/grid/9_5.png b/tools/lpc_extract/grid/9_5.png new file mode 100644 index 0000000..e9fe8af Binary files /dev/null and b/tools/lpc_extract/grid/9_5.png differ diff --git a/tools/lpc_extract/grid/9_6.png b/tools/lpc_extract/grid/9_6.png new file mode 100644 index 0000000..4e9903f Binary files /dev/null and b/tools/lpc_extract/grid/9_6.png differ diff --git a/tools/lpc_extract/grid/9_7.png b/tools/lpc_extract/grid/9_7.png new file mode 100644 index 0000000..26a5e4d Binary files /dev/null and b/tools/lpc_extract/grid/9_7.png differ diff --git a/tools/lpc_extract/grid/9_8.png b/tools/lpc_extract/grid/9_8.png new file mode 100644 index 0000000..e8660c4 Binary files /dev/null and b/tools/lpc_extract/grid/9_8.png differ diff --git a/tools/lpc_extract/grid/9_9.png b/tools/lpc_extract/grid/9_9.png new file mode 100644 index 0000000..ef30308 Binary files /dev/null and b/tools/lpc_extract/grid/9_9.png differ diff --git a/tools/lpc_extract/grid_annotated.png b/tools/lpc_extract/grid_annotated.png new file mode 100644 index 0000000..499b53b Binary files /dev/null and b/tools/lpc_extract/grid_annotated.png differ diff --git a/tools/lpc_extract/grid_annotated_full.png b/tools/lpc_extract/grid_annotated_full.png new file mode 100644 index 0000000..c5ee123 Binary files /dev/null and b/tools/lpc_extract/grid_annotated_full.png differ diff --git a/tools/lpc_extract/inspect_gas.py b/tools/lpc_extract/inspect_gas.py new file mode 100644 index 0000000..43c7045 --- /dev/null +++ b/tools/lpc_extract/inspect_gas.py @@ -0,0 +1,10 @@ +import glob +from PIL import Image + +gas = Image.open('/home/enne2/dev/mice/assets/Rat/BMP_1_GAS_DOWN.png').convert('RGB') +colors = set(gas.getdata()) +print("Colors in GAS_DOWN:", colors) + +flower = Image.open('/home/enne2/dev/mice/assets/Rat/BMP_1_FLOWER_1.png').convert('RGB') +colors = set(flower.getdata()) +print("Colors in FLOWER_1:", colors) diff --git a/tools/lpc_extract/inspect_lpc.py b/tools/lpc_extract/inspect_lpc.py new file mode 100644 index 0000000..91a3ed3 --- /dev/null +++ b/tools/lpc_extract/inspect_lpc.py @@ -0,0 +1,11 @@ +from PIL import Image +import subprocess + +src_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +# Extract the 3x4 block from tx=3 to 5, ty=0 to 3 +# Also extract ty=4 just in case +box = (3 * 32, 0, 6 * 32, 5 * 32) +block = src_img.crop(box) +block.save('/home/enne2/dev/mice/tools/lpc_extract/lpc_grass_dirt.png') +print("Created lpc_grass_dirt.png") diff --git a/tools/lpc_extract/lpc_grass_dirt.png b/tools/lpc_extract/lpc_grass_dirt.png new file mode 100644 index 0000000..19cf07e Binary files /dev/null and b/tools/lpc_extract/lpc_grass_dirt.png differ diff --git a/tools/lpc_extract/montage_originals.py b/tools/lpc_extract/montage_originals.py new file mode 100644 index 0000000..4c2e1e3 --- /dev/null +++ b/tools/lpc_extract/montage_originals.py @@ -0,0 +1,18 @@ +import glob +import subprocess +import os + +files = sorted(glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png')) + +# Use ImageMagick montage to create a preview with labels +cmd = [ + 'montage', + '-label', '%t', # Use the filename (without extension) as label + *files, + '-geometry', '+2+2', + '-background', 'transparent', + '-tile', '6x', + '/home/enne2/dev/mice/tools/lpc_extract/originals_with_labels.png' +] +subprocess.run(cmd) +print("Done creating originals_with_labels.png") diff --git a/tools/lpc_extract/originals_with_labels.png b/tools/lpc_extract/originals_with_labels.png new file mode 100644 index 0000000..590081c Binary files /dev/null and b/tools/lpc_extract/originals_with_labels.png differ diff --git a/tools/lpc_extract/preview.png b/tools/lpc_extract/preview.png new file mode 100644 index 0000000..ccb1a7f Binary files /dev/null and b/tools/lpc_extract/preview.png differ diff --git a/tools/lpc_extract/recolor.py b/tools/lpc_extract/recolor.py new file mode 100644 index 0000000..8f95d8b --- /dev/null +++ b/tools/lpc_extract/recolor.py @@ -0,0 +1,45 @@ +import glob +import os +from PIL import Image + +# Original colors mapped to LPC approximate equivalents +color_map = { + (0, 128, 0): (92, 154, 42), # Dark Green + (0, 255, 0): (124, 184, 47), # Bright Green + (128, 128, 128): (173, 132, 79), # Grey -> Brown dirt + (192, 192, 192): (248, 188, 118), # Light Grey -> Light dirt/sand + (0, 0, 0): (107, 60, 46), # Black -> Dark brown (for softer LPC look) + (255, 255, 0): (224, 156, 76), # Yellow -> LPC Yellow/Orange + (255, 255, 255): (244, 215, 160), # White -> LPC Light bone/sand + (0, 255, 255): (164, 221, 219), # Cyan + (255, 0, 255): (210, 100, 150), # Magenta -> Pink + (255, 0, 0): (180, 50, 50), # Red +} + +def recolor_pixel(px): + # px is (r, g, b) or (r, g, b, a) + rgb = px[:3] + if rgb in color_map: + new_rgb = color_map[rgb] + if len(px) == 4: + return new_rgb + (px[3],) + return new_rgb + + # If not exact match, find closest by euclidean distance + closest = min(color_map.keys(), key=lambda c: sum((a-b)**2 for a, b in zip(rgb, c))) + new_rgb = color_map[closest] + if len(px) == 4: + return new_rgb + (px[3],) + return new_rgb + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' + +for f in input_files: + img = Image.open(f).convert('RGBA') + new_data = [recolor_pixel(p) for p in img.getdata()] + img.putdata(new_data) + + basename = os.path.basename(f) + img.save(os.path.join(out_dir, basename)) + print(f"Recolored {basename}") diff --git a/tools/lpc_extract/restyle.py b/tools/lpc_extract/restyle.py new file mode 100644 index 0000000..5abaa8c --- /dev/null +++ b/tools/lpc_extract/restyle.py @@ -0,0 +1,115 @@ +import glob +import os +import random +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +# Extract textures from LPC +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +lpc_grass = get_lpc_texture(4, 1) +lpc_dirt = get_lpc_texture(7, 1) + +# Create 64x64 seamless textures by tiling +def make_64_texture(tile32): + tex = Image.new('RGBA', (64, 64)) + tex.paste(tile32, (0, 0)) + tex.paste(tile32, (32, 0)) + tex.paste(tile32, (0, 32)) + tex.paste(tile32, (32, 32)) + return tex + +tex_grass = make_64_texture(lpc_grass).load() +tex_dirt = make_64_texture(lpc_dirt).load() + +# Define color classes for the original sprites +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + if rgb in [(128, 128, 128), (192, 192, 192)]: + return 'DIRT' + if rgb == (0, 0, 0): + return 'HOLE' + return 'DETAIL' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +# Original colors mapped to LPC approximate equivalents (for details) +color_map = { + (255, 255, 0): (224, 156, 76), # Yellow + (255, 255, 255): (244, 215, 160), # White + (0, 255, 255): (164, 221, 219), # Cyan + (255, 0, 255): (210, 100, 150), # Magenta + (255, 0, 0): (180, 50, 50), # Red +} + +def closest_detail_color(rgb): + if rgb in color_map: + return color_map[rgb] + # Fallback for unexpected colors + return rgb + +for f in input_files: + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + # First pass: map base textures + classes = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + classes[(x, y)] = cls + + if cls == 'GRASS': + out_pixels[x, y] = tex_grass[x, y] + elif cls == 'DIRT': + out_pixels[x, y] = tex_dirt[x, y] + elif cls == 'HOLE': + # Dark deep hole + out_pixels[x, y] = (30, 20, 15, 255) + else: + out_pixels[x, y] = closest_detail_color(px) + (255,) + + # Second pass: "Style del disegno" - add shadows and jagged edges where grass meets dirt + for y in range(height): + for x in range(width): + if classes[(x, y)] == 'DIRT': + # Check for grass above to cast shadow + if y > 0 and classes[(x, y-1)] == 'GRASS': + # Darken the dirt pixel (shadow) + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.6), int(g*0.6), int(b*0.6), a) + + # Randomly drop a jagged grass blade + if random.random() < 0.4: + out_pixels[x, y] = tex_grass[x, y] + # Maybe extend it 1 more pixel down + if y + 1 < height and random.random() < 0.5: + out_pixels[x, y+1] = tex_grass[x, y+1] + + # Check for grass on sides for soft shadow/border + elif (x > 0 and classes[(x-1, y)] == 'GRASS') or (x < width-1 and classes[(x+1, y)] == 'GRASS'): + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.7), int(g*0.7), int(b*0.7), a) + if random.random() < 0.2: + out_pixels[x, y] = tex_grass[x, y] + + elif classes[(x, y)] == 'HOLE': + # Inner shadow for hole + if (y > 0 and classes[(x, y-1)] != 'HOLE') or (x > 0 and classes[(x-1, y)] != 'HOLE'): + out_pixels[x, y] = (10, 5, 5, 255) + + basename = os.path.basename(f) + out_img.save(os.path.join(out_dir, basename)) + +print("Completed style transfer!") diff --git a/tools/lpc_extract/restyle_v10.py b/tools/lpc_extract/restyle_v10.py new file mode 100644 index 0000000..89a112d --- /dev/null +++ b/tools/lpc_extract/restyle_v10.py @@ -0,0 +1,215 @@ +import glob +import os +import random +import math +from PIL import Image + +# LPC Bush Colors +C_DARK = (37, 86, 46, 255) +C_MED = (70, 130, 50, 255) +C_LIGHT = (92, 154, 42, 255) +C_BRIGHT = (124, 184, 47, 255) +C_SHADOW = (42, 23, 34, 150) +C_SHADOW_SOFT = (42, 23, 34, 70) +C_DIRT = (128, 128, 128, 255) + +def draw_wrapped_circle(pixels, w, h, cx, cy, r, color): + for y in range(int(cy - r - 1), int(cy + r + 2)): + for x in range(int(cx - r - 1), int(cx + r + 2)): + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x % w, y % h] = color + +def generate_seamless_hedge(w, h): + # Base is medium green, not dark! + img = Image.new('RGBA', (w, h), C_MED) + pixels = img.load() + + # Large clusters of base grass color + for _ in range((w * h) // 16): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(2.0, 3.5), C_LIGHT) + + # Highlights + for _ in range((w * h) // 32): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(1.0, 2.0), C_BRIGHT) + + # Tiny dark gaps + for _ in range((w * h) // 80): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(0.5, 1.2), C_DARK) + + return img + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + return 'DIRT' + +def alpha_blend(c1, c2): + a = c1[3] / 255.0 + r = int(c1[0] * a + c2[0] * (1 - a)) + g = int(c1[1] * a + c2[1] * (1 - a)) + b = int(c1[2] * a + c2[2] * (1 - a)) + return (r, g, b, 255) + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +base_hedge_64 = generate_seamless_hedge(64, 64) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + mask = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + if is_flower: + mask[(x, y)] = 'GRASS' + elif is_fx: + if cls == 'GRASS': + mask[(x, y)] = 'GRASS' + else: + mask[(x, y)] = 'DIRT' + else: + mask[(x, y)] = cls + + tile_hedge = base_hedge_64.copy() + tile_pixels = tile_hedge.load() + + if basename == 'BMP_1_GRASS_2.png': + for _ in range(8): + cx, cy = random.randint(16, 48), random.randint(16, 48) + tile_pixels[cx, cy] = (220, 50, 50, 255) + elif basename == 'BMP_1_GRASS_3.png': + for _ in range(12): + cx, cy = random.randint(16, 48), random.randint(16, 48) + tile_pixels[cx, cy] = (255, 255, 255, 255) + elif basename == 'BMP_1_GRASS_4.png': + for _ in range(20): + cx, cy = random.randint(20, 44), random.randint(20, 44) + draw_wrapped_circle(tile_pixels, 64, 64, cx, cy, random.uniform(1.0, 2.5), C_MED) + + for y in range(height): + for x in range(width): + if mask[(x, y)] == 'GRASS': + dist_to_dirt = 999 + for dy in range(-3, 4): + for dx in range(-3, 4): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'DIRT': + d = math.hypot(dx, dy) + if d < dist_to_dirt: + dist_to_dirt = d + + if dist_to_dirt <= 1.5: + dirt_below = (y+1 < height and mask[(x, y+1)] == 'DIRT') or (y+2 < height and mask[(x, y+2)] == 'DIRT') + if dirt_below: + out_pixels[x, y] = C_DARK if (x % 3) == 0 else C_MED + else: + out_pixels[x, y] = C_MED + elif dist_to_dirt <= 2.5: + out_pixels[x, y] = C_LIGHT + else: + out_pixels[x, y] = tile_pixels[x % 64, y % 64] + else: + orig_color = pixels[x, y][:3] + if orig_color == (0, 0, 0) and not is_fx: + # Replace debug dashed lines with dirt + orig_color = C_DIRT[:3] + + if orig_color == (0, 0, 0): + out_pixels[x, y] = (0, 0, 0, 255) + elif orig_color in [(128,128,128), (192,192,192)]: + dist_to_grass = 999 + for dy in range(-2, 3): + for dx in range(-2, 3): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'GRASS': + d = math.hypot(dx, dy) + if d < dist_to_grass: + dist_to_grass = d + base_c = orig_color + if dist_to_grass <= 1.5: + out_pixels[x, y] = alpha_blend(C_SHADOW, base_c) + elif dist_to_grass <= 2.5: + out_pixels[x, y] = alpha_blend(C_SHADOW_SOFT, base_c) + else: + out_pixels[x, y] = base_c + (255,) + else: + out_pixels[x, y] = orig_color + (255,) + + # Flowers logic + if is_flower: + def draw_circle(cx, cy, r, color, outline=None): + for fy in range(cy - r - 1, cy + r + 2): + for fx in range(cx - r - 1, cx + r + 2): + if 0 <= fx < width and 0 <= fy < height: + d = math.hypot(fx - cx, fy - cy) + if d <= r: + out_pixels[fx, fy] = color + elif outline and r < d <= r + 1.2: + if out_pixels[fx, fy] != color: + out_pixels[fx, fy] = outline + + def draw_petal(cx, cy, angle, length, pw, color, outline): + cos_a, sin_a = math.cos(angle), math.sin(angle) + size = int(length + pw) + for fy in range(cy - size, cy + size + 1): + for fx in range(cx - size, cx + size + 1): + if 0 <= fx < width and 0 <= fy < height: + dx, dy = fx - cx, fy - cy + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + if length > 0 and pw > 0: + val = (rx / length)**2 + (ry / pw)**2 + if val <= 1.0: + out_pixels[fx, fy] = color + elif val <= 1.5: + if out_pixels[fx, fy] != color: + out_pixels[fx, fy] = outline + + def draw_large_flower(cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width): + draw_circle(cx, cy + 3, petal_length + 1, (20, 50, 20, 200)) + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) if math.sin(angle) > 0 else petal_color + draw_petal(cx, cy, angle, petal_length, petal_width, pcolor, outline_color) + draw_circle(cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255)) + + if 'FLOWER_1' in basename: + draw_large_flower(32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5) + elif 'FLOWER_2' in basename: + draw_large_flower(16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + elif 'FLOWER_3' in basename: + draw_large_flower(32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6) + elif 'FLOWER_4' in basename: + draw_large_flower(32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6) + + if is_fx: + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + if get_class(px) != 'GRASS' and px not in [(128,128,128), (192,192,192), (0,0,0)]: + out_pixels[x, y] = px + (255,) + + out_img.save(os.path.join(out_dir, basename)) + +print("V10 - Bright LPC colors and fixed black borders!") diff --git a/tools/lpc_extract/restyle_v11.py b/tools/lpc_extract/restyle_v11.py new file mode 100644 index 0000000..643d20d --- /dev/null +++ b/tools/lpc_extract/restyle_v11.py @@ -0,0 +1,215 @@ +import glob +import os +import random +import math +from PIL import Image + +# Vibrant colors closer to the original 8-bit sprites, but rich and organic +C_DARK = (15, 110, 35, 255) +C_MED = (30, 155, 45, 255) +C_LIGHT = (45, 195, 60, 255) +C_BRIGHT = (70, 230, 80, 255) +C_SHADOW = (20, 50, 30, 100) # Softer, greener shadow instead of black/purple +C_SHADOW_SOFT = (20, 50, 30, 50) +C_DIRT = (128, 128, 128, 255) + +def draw_wrapped_circle(pixels, w, h, cx, cy, r, color): + for y in range(int(cy - r - 1), int(cy + r + 2)): + for x in range(int(cx - r - 1), int(cx + r + 2)): + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x % w, y % h] = color + +def generate_seamless_hedge(w, h): + img = Image.new('RGBA', (w, h), C_MED) + pixels = img.load() + + # Large clusters of base grass color + for _ in range((w * h) // 16): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(2.0, 3.5), C_LIGHT) + + # Highlights + for _ in range((w * h) // 32): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(1.0, 2.0), C_BRIGHT) + + # Tiny dark gaps + for _ in range((w * h) // 80): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(0.5, 1.2), C_DARK) + + return img + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + return 'DIRT' + +def alpha_blend(c1, c2): + a = c1[3] / 255.0 + r = int(c1[0] * a + c2[0] * (1 - a)) + g = int(c1[1] * a + c2[1] * (1 - a)) + b = int(c1[2] * a + c2[2] * (1 - a)) + return (r, g, b, 255) + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +base_hedge_64 = generate_seamless_hedge(64, 64) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + mask = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + if is_flower: + mask[(x, y)] = 'GRASS' + elif is_fx: + if cls == 'GRASS': + mask[(x, y)] = 'GRASS' + else: + mask[(x, y)] = 'DIRT' + else: + mask[(x, y)] = cls + + tile_hedge = base_hedge_64.copy() + tile_pixels = tile_hedge.load() + + if basename == 'BMP_1_GRASS_2.png': + for _ in range(8): + cx, cy = random.randint(16, 48), random.randint(16, 48) + tile_pixels[cx, cy] = (220, 50, 50, 255) + elif basename == 'BMP_1_GRASS_3.png': + for _ in range(12): + cx, cy = random.randint(16, 48), random.randint(16, 48) + tile_pixels[cx, cy] = (255, 255, 255, 255) + elif basename == 'BMP_1_GRASS_4.png': + for _ in range(20): + cx, cy = random.randint(20, 44), random.randint(20, 44) + draw_wrapped_circle(tile_pixels, 64, 64, cx, cy, random.uniform(1.0, 2.5), C_MED) + + for y in range(height): + for x in range(width): + if mask[(x, y)] == 'GRASS': + dist_to_dirt = 999 + for dy in range(-3, 4): + for dx in range(-3, 4): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'DIRT': + d = math.hypot(dx, dy) + if d < dist_to_dirt: + dist_to_dirt = d + + if dist_to_dirt <= 1.5: + dirt_below = (y+1 < height and mask[(x, y+1)] == 'DIRT') or (y+2 < height and mask[(x, y+2)] == 'DIRT') + if dirt_below: + # Solid dark green outline on the bottom (no more dashes!) + out_pixels[x, y] = C_DARK + else: + out_pixels[x, y] = C_MED + elif dist_to_dirt <= 2.5: + out_pixels[x, y] = C_MED + else: + out_pixels[x, y] = tile_pixels[x % 64, y % 64] + else: + orig_color = pixels[x, y][:3] + if orig_color == (0, 0, 0) and not is_fx: + # Replace debug dashed lines with dirt + orig_color = C_DIRT[:3] + + if orig_color == (0, 0, 0): + out_pixels[x, y] = (0, 0, 0, 255) + elif orig_color in [(128,128,128), (192,192,192)]: + dist_to_grass = 999 + for dy in range(-2, 3): + for dx in range(-2, 3): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'GRASS': + d = math.hypot(dx, dy) + if d < dist_to_grass: + dist_to_grass = d + base_c = orig_color + if dist_to_grass <= 1.5: + out_pixels[x, y] = alpha_blend(C_SHADOW, base_c) + elif dist_to_grass <= 2.5: + out_pixels[x, y] = alpha_blend(C_SHADOW_SOFT, base_c) + else: + out_pixels[x, y] = base_c + (255,) + else: + out_pixels[x, y] = orig_color + (255,) + + # Flowers logic + if is_flower: + def draw_circle(cx, cy, r, color, outline=None): + for fy in range(cy - r - 1, cy + r + 2): + for fx in range(cx - r - 1, cx + r + 2): + if 0 <= fx < width and 0 <= fy < height: + d = math.hypot(fx - cx, fy - cy) + if d <= r: + out_pixels[fx, fy] = color + elif outline and r < d <= r + 1.2: + if out_pixels[fx, fy] != color: + out_pixels[fx, fy] = outline + + def draw_petal(cx, cy, angle, length, pw, color, outline): + cos_a, sin_a = math.cos(angle), math.sin(angle) + size = int(length + pw) + for fy in range(cy - size, cy + size + 1): + for fx in range(cx - size, cx + size + 1): + if 0 <= fx < width and 0 <= fy < height: + dx, dy = fx - cx, fy - cy + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + if length > 0 and pw > 0: + val = (rx / length)**2 + (ry / pw)**2 + if val <= 1.0: + out_pixels[fx, fy] = color + elif val <= 1.5: + if out_pixels[fx, fy] != color: + out_pixels[fx, fy] = outline + + def draw_large_flower(cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width): + draw_circle(cx, cy + 3, petal_length + 1, (20, 50, 20, 200)) + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) if math.sin(angle) > 0 else petal_color + draw_petal(cx, cy, angle, petal_length, petal_width, pcolor, outline_color) + draw_circle(cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255)) + + if 'FLOWER_1' in basename: + draw_large_flower(32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5) + elif 'FLOWER_2' in basename: + draw_large_flower(16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + elif 'FLOWER_3' in basename: + draw_large_flower(32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6) + elif 'FLOWER_4' in basename: + draw_large_flower(32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6) + + if is_fx: + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + if get_class(px) != 'GRASS' and px not in [(128,128,128), (192,192,192), (0,0,0)]: + out_pixels[x, y] = px + (255,) + + out_img.save(os.path.join(out_dir, basename)) + +print("V11 - Vibrant 8-bit-like colors and NO dashed lines!") diff --git a/tools/lpc_extract/restyle_v2.py b/tools/lpc_extract/restyle_v2.py new file mode 100644 index 0000000..860b9f7 --- /dev/null +++ b/tools/lpc_extract/restyle_v2.py @@ -0,0 +1,91 @@ +import glob +import os +import random +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +lpc_grass = get_lpc_texture(4, 1) + +def make_64_texture(tile32): + tex = Image.new('RGBA', (64, 64)) + tex.paste(tile32, (0, 0)) + tex.paste(tile32, (32, 0)) + tex.paste(tile32, (0, 32)) + tex.paste(tile32, (32, 32)) + return tex + +tex_grass = make_64_texture(lpc_grass).load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + if rgb in [(128, 128, 128), (192, 192, 192)]: + return 'DIRT' # "Terreno" + if rgb == (0, 0, 0): + return 'HOLE' + return 'DETAIL' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + + # "Esplosione e gas... devono essere uguali all'originale" + if 'EXPLOSION' in basename or 'GAS' in basename: + img.save(os.path.join(out_dir, basename)) + continue + + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + classes = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + classes[(x, y)] = cls + + if cls == 'GRASS': + out_pixels[x, y] = tex_grass[x, y] + elif cls == 'DIRT': + # "compreso il grigio del terreno, devono essere uguali all'originale" + out_pixels[x, y] = px + (255,) + elif cls == 'HOLE': + out_pixels[x, y] = px + (255,) + else: + out_pixels[x, y] = px + (255,) # keep original detail colors too + + # Add shadow and grass overlapping the dirt, to keep the drawing style + for y in range(height): + for x in range(width): + if classes[(x, y)] == 'DIRT': + # Shadow from grass above + if y > 0 and classes[(x, y-1)] == 'GRASS': + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.6), int(g*0.6), int(b*0.6), a) + if random.random() < 0.4: + out_pixels[x, y] = tex_grass[x, y] + if y + 1 < height and random.random() < 0.5: + out_pixels[x, y+1] = tex_grass[x, y+1] + + # Soft shadow from grass on sides + elif (x > 0 and classes[(x-1, y)] == 'GRASS') or (x < width-1 and classes[(x+1, y)] == 'GRASS'): + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.7), int(g*0.7), int(b*0.7), a) + if random.random() < 0.2: + out_pixels[x, y] = tex_grass[x, y] + + out_img.save(os.path.join(out_dir, basename)) + +print("Restyle updated with original terrain and fx!") diff --git a/tools/lpc_extract/restyle_v3.py b/tools/lpc_extract/restyle_v3.py new file mode 100644 index 0000000..d474e21 --- /dev/null +++ b/tools/lpc_extract/restyle_v3.py @@ -0,0 +1,137 @@ +import glob +import os +import random +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +lpc_grass = get_lpc_texture(4, 1) + +def make_64_texture(tile32): + tex = Image.new('RGBA', (64, 64)) + tex.paste(tile32, (0, 0)) + tex.paste(tile32, (32, 0)) + tex.paste(tile32, (0, 32)) + tex.paste(tile32, (32, 32)) + return tex + +tex_grass = make_64_texture(lpc_grass).load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + if rgb in [(128, 128, 128), (192, 192, 192)]: + return 'DIRT' # Terrain, gas edge + if rgb == (0, 0, 0): + return 'HOLE' + return 'DETAIL' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +# Function to draw an LPC-style small flower +def draw_lpc_flower(pixels, cx, cy, color): + # Shadow + pixels[cx, cy+1] = (20, 50, 20, 255) + pixels[cx-1, cy+1] = (20, 50, 20, 255) + pixels[cx+1, cy+1] = (20, 50, 20, 255) + + # Petals + pixels[cx, cy] = color + pixels[cx-1, cy] = color + pixels[cx+1, cy] = color + pixels[cx, cy-1] = color + + # Center + pixels[cx, cy] = (240, 200, 50, 255) # Yellowish center + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + if is_flower: + # Fill entirely with grass + for y in range(height): + for x in range(width): + out_pixels[x, y] = tex_grass[x, y] + + # Draw LPC style flowers based on which file it is + if 'FLOWER_1' in basename: + draw_lpc_flower(out_pixels, 32, 32, (255, 255, 255, 255)) + draw_lpc_flower(out_pixels, 20, 40, (255, 255, 255, 255)) + draw_lpc_flower(out_pixels, 45, 20, (255, 255, 255, 255)) + elif 'FLOWER_2' in basename: + draw_lpc_flower(out_pixels, 20, 20, (220, 50, 50, 255)) + draw_lpc_flower(out_pixels, 40, 20, (220, 50, 50, 255)) + draw_lpc_flower(out_pixels, 30, 40, (220, 50, 50, 255)) + elif 'FLOWER_3' in basename: + draw_lpc_flower(out_pixels, 32, 32, (220, 100, 200, 255)) + elif 'FLOWER_4' in basename: + draw_lpc_flower(out_pixels, 20, 20, (100, 180, 255, 255)) + draw_lpc_flower(out_pixels, 40, 40, (100, 180, 255, 255)) + + out_img.save(os.path.join(out_dir, basename)) + continue + + classes = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + + # For FX, light grey (192,192,192) could be GAS or terrain. + # Original gas has 255,255,255 and 192,192,192. + if is_fx: + # If it's bright green or dark green, replace with grass + if cls == 'GRASS': + classes[(x, y)] = 'GRASS' + out_pixels[x, y] = tex_grass[x, y] + else: + # Keep all other original pixels exactly the same for FX + classes[(x, y)] = 'DETAIL' # Don't apply dirt shadows to gas + if cls == 'DIRT' and px == (128, 128, 128): + classes[(x, y)] = 'DIRT' # Keep dirt as dirt so it gets shadows + out_pixels[x, y] = px + (255,) + else: + classes[(x, y)] = cls + if cls == 'GRASS': + out_pixels[x, y] = tex_grass[x, y] + else: + out_pixels[x, y] = px + (255,) + + # Add shadow and grass overlapping the dirt, to keep the drawing style + for y in range(height): + for x in range(width): + if classes[(x, y)] == 'DIRT': + # Shadow from grass above + if y > 0 and classes[(x, y-1)] == 'GRASS': + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.6), int(g*0.6), int(b*0.6), a) + if random.random() < 0.4: + out_pixels[x, y] = tex_grass[x, y] + if y + 1 < height and random.random() < 0.5: + out_pixels[x, y+1] = tex_grass[x, y+1] + + # Soft shadow from grass on sides + elif (x > 0 and classes[(x-1, y)] == 'GRASS') or (x < width-1 and classes[(x+1, y)] == 'GRASS'): + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.7), int(g*0.7), int(b*0.7), a) + if random.random() < 0.2: + out_pixels[x, y] = tex_grass[x, y] + + out_img.save(os.path.join(out_dir, basename)) + +print("Restyle updated with LPC flowers and FX grass!") diff --git a/tools/lpc_extract/restyle_v4.py b/tools/lpc_extract/restyle_v4.py new file mode 100644 index 0000000..9a9600d --- /dev/null +++ b/tools/lpc_extract/restyle_v4.py @@ -0,0 +1,176 @@ +import glob +import os +import random +import math +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +lpc_grass = get_lpc_texture(4, 1) + +def make_64_texture(tile32): + tex = Image.new('RGBA', (64, 64)) + tex.paste(tile32, (0, 0)) + tex.paste(tile32, (32, 0)) + tex.paste(tile32, (0, 32)) + tex.paste(tile32, (32, 32)) + return tex + +tex_grass = make_64_texture(lpc_grass).load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + if rgb in [(128, 128, 128), (192, 192, 192)]: + return 'DIRT' + if rgb == (0, 0, 0): + return 'HOLE' + return 'DETAIL' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +def draw_circle(pixels, cx, cy, r, color, outline=None): + for y in range(cy - r - 1, cy + r + 2): + for x in range(cx - r - 1, cx + r + 2): + if 0 <= x < 64 and 0 <= y < 64: + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x, y] = color + elif outline and r < d <= r + 1.2: + # Only draw outline if it's not overriding the inner color + current = pixels[x, y] + if current != color: + pixels[x, y] = outline + +def draw_petal(pixels, cx, cy, angle, length, width, color, outline): + # simple ellipse rotated + cos_a = math.cos(angle) + sin_a = math.sin(angle) + + # iterate over a bounding box + size = int(length + width) + for y in range(cy - size, cy + size + 1): + for x in range(cx - size, cx + size + 1): + if 0 <= x < 64 and 0 <= y < 64: + dx = x - cx + dy = y - cy + + # rotate back + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + + # ellipse equation: (rx/length)^2 + (ry/width)^2 <= 1 + if length > 0 and width > 0: + val = (rx / length)**2 + (ry / width)**2 + if val <= 1.0: + pixels[x, y] = color + elif val <= 1.5: + if pixels[x, y] != color: + pixels[x, y] = outline + +def draw_large_flower(pixels, cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width): + # Shadow under the flower + draw_circle(pixels, cx, cy + 3, petal_length + 1, (20, 50, 20, 200)) + + # Petals + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + # Add slight shading to bottom petals + if math.sin(angle) > 0: + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) + else: + pcolor = petal_color + + # Draw the petal outline first + draw_petal(pixels, cx, cy, angle, petal_length, petal_width, pcolor, outline_color) + + # Draw center + draw_circle(pixels, cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255)) + # Center highlight + pixels[cx-1, cy-1] = (255, 255, 200, 255) + pixels[cx, cy-1] = (255, 255, 200, 255) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + if is_flower: + for y in range(height): + for x in range(width): + out_pixels[x, y] = tex_grass[x, y] + + # Draw LPC style large flowers + if 'FLOWER_1' in basename: + # White Daisy + draw_large_flower(out_pixels, 32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5) + elif 'FLOWER_2' in basename: + # 3 Red flowers + draw_large_flower(out_pixels, 16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(out_pixels, 48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(out_pixels, 32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + elif 'FLOWER_3' in basename: + # Pink flower + draw_large_flower(out_pixels, 32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6) + elif 'FLOWER_4' in basename: + # Blue flower + draw_large_flower(out_pixels, 32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6) + + out_img.save(os.path.join(out_dir, basename)) + continue + + classes = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + + if is_fx: + if cls == 'GRASS': + classes[(x, y)] = 'GRASS' + out_pixels[x, y] = tex_grass[x, y] + else: + classes[(x, y)] = 'DETAIL' + if cls == 'DIRT' and px == (128, 128, 128): + classes[(x, y)] = 'DIRT' + out_pixels[x, y] = px + (255,) + else: + classes[(x, y)] = cls + if cls == 'GRASS': + out_pixels[x, y] = tex_grass[x, y] + else: + out_pixels[x, y] = px + (255,) + + for y in range(height): + for x in range(width): + if classes[(x, y)] == 'DIRT': + if y > 0 and classes[(x, y-1)] == 'GRASS': + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.6), int(g*0.6), int(b*0.6), a) + if random.random() < 0.4: + out_pixels[x, y] = tex_grass[x, y] + if y + 1 < height and random.random() < 0.5: + out_pixels[x, y+1] = tex_grass[x, y+1] + + elif (x > 0 and classes[(x-1, y)] == 'GRASS') or (x < width-1 and classes[(x+1, y)] == 'GRASS'): + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.7), int(g*0.7), int(b*0.7), a) + if random.random() < 0.2: + out_pixels[x, y] = tex_grass[x, y] + + out_img.save(os.path.join(out_dir, basename)) + +print("Restyle updated with large LPC flowers!") diff --git a/tools/lpc_extract/restyle_v5.py b/tools/lpc_extract/restyle_v5.py new file mode 100644 index 0000000..ec6c5d6 --- /dev/null +++ b/tools/lpc_extract/restyle_v5.py @@ -0,0 +1,158 @@ +import glob +import os +import random +import math +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +grass_tiles = [ + get_lpc_texture(3, 1), get_lpc_texture(4, 1), get_lpc_texture(5, 1), + get_lpc_texture(3, 2), get_lpc_texture(4, 2), get_lpc_texture(5, 2) +] + +def make_random_64_grass(): + tex = Image.new('RGBA', (64, 64)) + tex.paste(random.choice(grass_tiles), (0, 0)) + tex.paste(random.choice(grass_tiles), (32, 0)) + tex.paste(random.choice(grass_tiles), (0, 32)) + tex.paste(random.choice(grass_tiles), (32, 32)) + return tex.load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + if rgb in [(128, 128, 128), (192, 192, 192)]: + return 'DIRT' + if rgb == (0, 0, 0): + return 'HOLE' + return 'DETAIL' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +def draw_circle(pixels, cx, cy, r, color, outline=None): + for y in range(cy - r - 1, cy + r + 2): + for x in range(cx - r - 1, cx + r + 2): + if 0 <= x < 64 and 0 <= y < 64: + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x, y] = color + elif outline and r < d <= r + 1.2: + current = pixels[x, y] + if current != color: + pixels[x, y] = outline + +def draw_petal(pixels, cx, cy, angle, length, width, color, outline): + cos_a = math.cos(angle) + sin_a = math.sin(angle) + size = int(length + width) + for y in range(cy - size, cy + size + 1): + for x in range(cx - size, cx + size + 1): + if 0 <= x < 64 and 0 <= y < 64: + dx = x - cx + dy = y - cy + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + if length > 0 and width > 0: + val = (rx / length)**2 + (ry / width)**2 + if val <= 1.0: + pixels[x, y] = color + elif val <= 1.5: + if pixels[x, y] != color: + pixels[x, y] = outline + +def draw_large_flower(pixels, cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width): + draw_circle(pixels, cx, cy + 3, petal_length + 1, (20, 50, 20, 200)) + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + if math.sin(angle) > 0: + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) + else: + pcolor = petal_color + draw_petal(pixels, cx, cy, angle, petal_length, petal_width, pcolor, outline_color) + draw_circle(pixels, cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255)) + pixels[cx-1, cy-1] = (255, 255, 200, 255) + pixels[cx, cy-1] = (255, 255, 200, 255) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + # Generate a unique grass texture for this sprite + tex_grass = make_random_64_grass() + + if is_flower: + for y in range(height): + for x in range(width): + out_pixels[x, y] = tex_grass[x, y] + + if 'FLOWER_1' in basename: + draw_large_flower(out_pixels, 32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5) + elif 'FLOWER_2' in basename: + draw_large_flower(out_pixels, 16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(out_pixels, 48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(out_pixels, 32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + elif 'FLOWER_3' in basename: + draw_large_flower(out_pixels, 32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6) + elif 'FLOWER_4' in basename: + draw_large_flower(out_pixels, 32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6) + + out_img.save(os.path.join(out_dir, basename)) + continue + + classes = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + + if is_fx: + if cls == 'GRASS': + classes[(x, y)] = 'GRASS' + out_pixels[x, y] = tex_grass[x, y] + else: + classes[(x, y)] = 'DETAIL' + if cls == 'DIRT' and px == (128, 128, 128): + classes[(x, y)] = 'DIRT' + out_pixels[x, y] = px + (255,) + else: + classes[(x, y)] = cls + if cls == 'GRASS': + out_pixels[x, y] = tex_grass[x, y] + else: + out_pixels[x, y] = px + (255,) + + for y in range(height): + for x in range(width): + if classes[(x, y)] == 'DIRT': + if y > 0 and classes[(x, y-1)] == 'GRASS': + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.6), int(g*0.6), int(b*0.6), a) + if random.random() < 0.4: + out_pixels[x, y] = tex_grass[x, y] + if y + 1 < height and random.random() < 0.5: + out_pixels[x, y+1] = tex_grass[x, y+1] + + elif (x > 0 and classes[(x-1, y)] == 'GRASS') or (x < width-1 and classes[(x+1, y)] == 'GRASS'): + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.7), int(g*0.7), int(b*0.7), a) + if random.random() < 0.2: + out_pixels[x, y] = tex_grass[x, y] + + out_img.save(os.path.join(out_dir, basename)) + +print("Restyle updated with varied grass!") diff --git a/tools/lpc_extract/restyle_v6.py b/tools/lpc_extract/restyle_v6.py new file mode 100644 index 0000000..0e1ad07 --- /dev/null +++ b/tools/lpc_extract/restyle_v6.py @@ -0,0 +1,213 @@ +import glob +import os +import random +import math +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +lpc_grass = get_lpc_texture(4, 1) + +def make_64_texture(tile32): + tex = Image.new('RGBA', (64, 64)) + tex.paste(tile32, (0, 0)) + tex.paste(tile32, (32, 0)) + tex.paste(tile32, (0, 32)) + tex.paste(tile32, (32, 32)) + return tex + +tex_grass = make_64_texture(lpc_grass).load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + if rgb in [(128, 128, 128), (192, 192, 192)]: + return 'DIRT' + if rgb == (0, 0, 0): + return 'HOLE' + return 'DETAIL' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +def draw_circle(pixels, cx, cy, r, color, outline=None, w=64, h=64): + for y in range(cy - r - 1, cy + r + 2): + for x in range(cx - r - 1, cx + r + 2): + if 0 <= x < w and 0 <= y < h: + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x, y] = color + elif outline and r < d <= r + 1.2: + if pixels[x, y] != color: + pixels[x, y] = outline + +def draw_petal(pixels, cx, cy, angle, length, width, color, outline, w=64, h=64): + cos_a = math.cos(angle) + sin_a = math.sin(angle) + size = int(length + width) + for y in range(cy - size, cy + size + 1): + for x in range(cx - size, cx + size + 1): + if 0 <= x < w and 0 <= y < h: + dx = x - cx + dy = y - cy + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + if length > 0 and width > 0: + val = (rx / length)**2 + (ry / width)**2 + if val <= 1.0: + pixels[x, y] = color + elif val <= 1.5: + if pixels[x, y] != color: + pixels[x, y] = outline + +def draw_large_flower(pixels, cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width, w=64, h=64): + draw_circle(pixels, cx, cy + 3, petal_length + 1, (20, 50, 20, 200), w=w, h=h) + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + if math.sin(angle) > 0: + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) + else: + pcolor = petal_color + draw_petal(pixels, cx, cy, angle, petal_length, petal_width, pcolor, outline_color, w, h) + draw_circle(pixels, cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255), w=w, h=h) + if cx-1 >= 0 and cy-1 >= 0: pixels[cx-1, cy-1] = (255, 255, 200, 255) + if cy-1 >= 0: pixels[cx, cy-1] = (255, 255, 200, 255) + +def add_tall_grass(pixels, num_patches, w=64, h=64): + for _ in range(num_patches): + bx = random.randint(5, max(5, w-6)) + by = random.randint(5, max(5, h-6)) + for _ in range(random.randint(4, 8)): + x = bx + random.randint(-4, 4) + y = by + random.randint(-4, 4) + height_g = random.randint(3, 6) + for dy in range(height_g): + if 0 <= x < w and 0 <= y - dy < h: + if dy == 0: + pixels[x, y-dy] = (20, 50, 20, 255) + else: + pixels[x, y-dy] = (140, 200, 60, 255) + if random.random() < 0.5 and 0 <= x+1 < w and 0 <= y < h: + pixels[x+1, y] = (50, 100, 30, 255) + +def add_pebbles(pixels, num_patches, w=64, h=64): + for _ in range(num_patches): + bx = random.randint(5, max(5, w-6)) + by = random.randint(5, max(5, h-6)) + if by+1 < h: + pixels[bx, by+1] = (20, 40, 20, 255) + if bx+1 < w: pixels[bx+1, by+1] = (20, 40, 20, 255) + pixels[bx, by] = (150, 150, 150, 255) + if bx+1 < w: pixels[bx+1, by] = (120, 120, 120, 255) + if by-1 >= 0: pixels[bx, by-1] = (180, 180, 180, 255) + if random.random() > 0.5 and bx-1 >= 0: + pixels[bx-1, by] = (130, 130, 130, 255) + +def add_tiny_flowers(pixels, num_patches, color, w=64, h=64): + for _ in range(num_patches): + bx = random.randint(5, max(5, w-6)) + by = random.randint(5, max(5, h-6)) + for _ in range(random.randint(3, 6)): + x = bx + random.randint(-5, 5) + y = by + random.randint(-5, 5) + if 0 <= x < w and 0 <= y < h: + pixels[x, y] = color + if y+1 < h: + pixels[x, y+1] = (20, 50, 20, 255) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + for y in range(height): + for x in range(width): + out_pixels[x, y] = tex_grass[x % 64, y % 64] + + if basename in ['BMP_1_GRASS_1.png']: + pass + elif basename in ['BMP_1_GRASS_2.png']: + add_tall_grass(out_pixels, 8, width, height) + elif basename in ['BMP_1_GRASS_3.png']: + add_pebbles(out_pixels, 5, width, height) + add_tiny_flowers(out_pixels, 3, (255, 255, 255, 255), width, height) + elif basename in ['BMP_1_GRASS_4.png']: + add_tiny_flowers(out_pixels, 5, (255, 200, 50, 255), width, height) + add_tall_grass(out_pixels, 3, width, height) + elif not is_fx and not is_flower: + # Add slight variation to other non-fx tiles + if random.random() < 0.3: + add_tall_grass(out_pixels, 2, width, height) + + if is_flower: + if 'FLOWER_1' in basename: + add_tall_grass(out_pixels, 4, width, height) + draw_large_flower(out_pixels, 32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5, width, height) + elif 'FLOWER_2' in basename: + add_tiny_flowers(out_pixels, 3, (255, 255, 255, 255), width, height) + draw_large_flower(out_pixels, 16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4, width, height) + draw_large_flower(out_pixels, 48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4, width, height) + draw_large_flower(out_pixels, 32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4, width, height) + elif 'FLOWER_3' in basename: + add_tall_grass(out_pixels, 3, width, height) + draw_large_flower(out_pixels, 32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6, width, height) + elif 'FLOWER_4' in basename: + add_pebbles(out_pixels, 2, width, height) + draw_large_flower(out_pixels, 32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6, width, height) + + out_img.save(os.path.join(out_dir, basename)) + continue + + classes = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + + if is_fx: + if cls == 'GRASS': + classes[(x, y)] = 'GRASS' + else: + classes[(x, y)] = 'DETAIL' + if cls == 'DIRT' and px == (128, 128, 128): + classes[(x, y)] = 'DIRT' + out_pixels[x, y] = px + (255,) + else: + classes[(x, y)] = cls + if cls == 'GRASS': + pass + else: + out_pixels[x, y] = px + (255,) + + for y in range(height): + for x in range(width): + if classes[(x, y)] == 'DIRT': + if y > 0 and classes[(x, y-1)] == 'GRASS': + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.6), int(g*0.6), int(b*0.6), a) + if random.random() < 0.4: + out_pixels[x, y] = tex_grass[x % 64, y % 64] + if y + 1 < height and random.random() < 0.5: + out_pixels[x, y+1] = tex_grass[x % 64, (y+1) % 64] + + elif (x > 0 and classes[(x-1, y)] == 'GRASS') or (x < width-1 and classes[(x+1, y)] == 'GRASS'): + r, g, b, a = out_pixels[x, y] + out_pixels[x, y] = (int(r*0.7), int(g*0.7), int(b*0.7), a) + if random.random() < 0.2: + out_pixels[x, y] = tex_grass[x % 64, y % 64] + + out_img.save(os.path.join(out_dir, basename)) + +print("Restyle updated with rich grass decorations and flexible sizes!") diff --git a/tools/lpc_extract/restyle_v7.py b/tools/lpc_extract/restyle_v7.py new file mode 100644 index 0000000..45b2332 --- /dev/null +++ b/tools/lpc_extract/restyle_v7.py @@ -0,0 +1,150 @@ +import glob +import os +import random +import math +from PIL import Image + +# Read LPC for textures +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +grass_tiles = [ + get_lpc_texture(3, 1), get_lpc_texture(4, 1), get_lpc_texture(5, 1), + get_lpc_texture(3, 2), get_lpc_texture(4, 2), get_lpc_texture(5, 2) +] + +def make_random_64_grass(): + tex = Image.new('RGBA', (64, 64)) + tex.paste(random.choice(grass_tiles), (0, 0)) + tex.paste(random.choice(grass_tiles), (32, 0)) + tex.paste(random.choice(grass_tiles), (0, 32)) + tex.paste(random.choice(grass_tiles), (32, 32)) + return tex.load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + return 'DIRT' + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +def alpha_blend(c1, c2): + # c1 is foreground (has alpha), c2 is background (RGB) + a = c1[3] / 255.0 + r = int(c1[0] * a + c2[0] * (1 - a)) + g = int(c1[1] * a + c2[1] * (1 - a)) + b = int(c1[2] * a + c2[2] * (1 - a)) + return (r, g, b, 255) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + # Determine mask + # For FX/Flowers, we just treat the whole thing as GRASS mask, except for original dirt? + # Wait, the original game didn't have paths in FX/Flower tiles, they were solid grass! + # Wait, in the earlier version, GAS_DOWN had a cave hole in it. + + mask = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + if is_flower: + mask[(x, y)] = 'GRASS' + elif is_fx: + if cls == 'GRASS': + mask[(x, y)] = 'GRASS' + else: + mask[(x, y)] = 'DIRT' + else: + mask[(x, y)] = cls + + tex_grass = make_random_64_grass() + + for y in range(height): + for x in range(width): + if mask[(x, y)] == 'GRASS': + # Calculate distance to DIRT + dist_to_dirt = 999 + # Simple search in 3x3 and 5x5 + for dy in range(-3, 4): + for dx in range(-3, 4): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'DIRT': + d = math.hypot(dx, dy) + if d < dist_to_dirt: + dist_to_dirt = d + + if dist_to_dirt <= 1.5: + # Border pixel. Determine if it's bottom edge or top/side. + # It's bottom edge if the dirt is BELOW it. + dirt_below = (y+1 < height and mask[(x, y+1)] == 'DIRT') or (y+2 < height and mask[(x, y+2)] == 'DIRT') + if dirt_below: + # Add jaggedness + if (x % 3) == 0: + out_pixels[x, y] = (37, 86, 46, 255) + else: + out_pixels[x, y] = (70, 130, 50, 255) + else: + out_pixels[x, y] = (70, 130, 50, 255) + elif dist_to_dirt <= 2.5: + out_pixels[x, y] = (92, 154, 42, 255) + else: + out_pixels[x, y] = tex_grass[x % 64, y % 64] + else: + # DIRT + # Keep original color + orig_color = pixels[x, y][:3] + if orig_color == (0, 0, 0): # Hole + out_pixels[x, y] = (0, 0, 0, 255) + elif orig_color in [(128,128,128), (192,192,192)]: + # Add shadow if adjacent to grass + dist_to_grass = 999 + for dy in range(-2, 3): + for dx in range(-2, 3): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'GRASS': + d = math.hypot(dx, dy) + if d < dist_to_grass: + dist_to_grass = d + + base_c = orig_color + if dist_to_grass <= 1.5: + shadow = (42, 23, 34, 150) + out_pixels[x, y] = alpha_blend(shadow, base_c) + elif dist_to_grass <= 2.5: + shadow = (42, 23, 34, 70) + out_pixels[x, y] = alpha_blend(shadow, base_c) + else: + out_pixels[x, y] = base_c + (255,) + else: + # FX details etc + out_pixels[x, y] = orig_color + (255,) + + # Draw original FX back on top + if is_fx: + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + if get_class(px) != 'GRASS' and px not in [(128,128,128), (192,192,192), (0,0,0)]: + out_pixels[x, y] = px + (255,) + + out_img.save(os.path.join(out_dir, basename)) + +print("Hedge styling applied!") diff --git a/tools/lpc_extract/restyle_v8.py b/tools/lpc_extract/restyle_v8.py new file mode 100644 index 0000000..22a9b96 --- /dev/null +++ b/tools/lpc_extract/restyle_v8.py @@ -0,0 +1,204 @@ +import glob +import os +import random +import math +from PIL import Image + +lpc_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +def get_lpc_texture(tx, ty): + box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) + return lpc_img.crop(box) + +grass_tiles = [ + get_lpc_texture(3, 1), get_lpc_texture(4, 1), get_lpc_texture(5, 1), + get_lpc_texture(3, 2), get_lpc_texture(4, 2), get_lpc_texture(5, 2) +] + +def make_random_64_grass(): + tex = Image.new('RGBA', (64, 64)) + tex.paste(random.choice(grass_tiles), (0, 0)) + tex.paste(random.choice(grass_tiles), (32, 0)) + tex.paste(random.choice(grass_tiles), (0, 32)) + tex.paste(random.choice(grass_tiles), (32, 32)) + return tex.load() + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + return 'DIRT' + +def alpha_blend(c1, c2): + a = c1[3] / 255.0 + r = int(c1[0] * a + c2[0] * (1 - a)) + g = int(c1[1] * a + c2[1] * (1 - a)) + b = int(c1[2] * a + c2[2] * (1 - a)) + return (r, g, b, 255) + +def draw_circle(pixels, cx, cy, r, color, outline=None, w=64, h=64): + for y in range(cy - r - 1, cy + r + 2): + for x in range(cx - r - 1, cx + r + 2): + if 0 <= x < w and 0 <= y < h: + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x, y] = color + elif outline and r < d <= r + 1.2: + if pixels[x, y] != color: + pixels[x, y] = outline + +def draw_petal(pixels, cx, cy, angle, length, width, color, outline, w=64, h=64): + cos_a = math.cos(angle) + sin_a = math.sin(angle) + size = int(length + width) + for y in range(cy - size, cy + size + 1): + for x in range(cx - size, cx + size + 1): + if 0 <= x < w and 0 <= y < h: + dx = x - cx + dy = y - cy + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + if length > 0 and width > 0: + val = (rx / length)**2 + (ry / width)**2 + if val <= 1.0: + pixels[x, y] = color + elif val <= 1.5: + if pixels[x, y] != color: + pixels[x, y] = outline + +def draw_large_flower(pixels, cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width, w=64, h=64): + draw_circle(pixels, cx, cy + 3, petal_length + 1, (20, 50, 20, 200), w=w, h=h) + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + if math.sin(angle) > 0: + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) + else: + pcolor = petal_color + draw_petal(pixels, cx, cy, angle, petal_length, petal_width, pcolor, outline_color, w, h) + draw_circle(pixels, cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255), w=w, h=h) + +def add_tiny_flowers(pixels, num_patches, color, mask, w=64, h=64): + for _ in range(num_patches): + bx = random.randint(5, max(5, w-6)) + by = random.randint(5, max(5, h-6)) + if mask.get((bx, by)) == 'GRASS': + for _ in range(random.randint(3, 6)): + x = bx + random.randint(-5, 5) + y = by + random.randint(-5, 5) + if 0 <= x < w and 0 <= y < h and mask.get((x, y)) == 'GRASS': + pixels[x, y] = color + if y+1 < h and mask.get((x, y+1)) == 'GRASS': + pixels[x, y+1] = (20, 50, 20, 255) + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + mask = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + if is_flower: + mask[(x, y)] = 'GRASS' + elif is_fx: + if cls == 'GRASS': + mask[(x, y)] = 'GRASS' + else: + mask[(x, y)] = 'DIRT' + else: + mask[(x, y)] = cls + + tex_grass = make_random_64_grass() + + for y in range(height): + for x in range(width): + if mask[(x, y)] == 'GRASS': + dist_to_dirt = 999 + for dy in range(-3, 4): + for dx in range(-3, 4): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'DIRT': + d = math.hypot(dx, dy) + if d < dist_to_dirt: + dist_to_dirt = d + + if dist_to_dirt <= 1.5: + dirt_below = (y+1 < height and mask[(x, y+1)] == 'DIRT') or (y+2 < height and mask[(x, y+2)] == 'DIRT') + if dirt_below: + if (x % 3) == 0: + out_pixels[x, y] = (37, 86, 46, 255) + else: + out_pixels[x, y] = (70, 130, 50, 255) + else: + out_pixels[x, y] = (70, 130, 50, 255) + elif dist_to_dirt <= 2.5: + out_pixels[x, y] = (92, 154, 42, 255) + else: + out_pixels[x, y] = tex_grass[x % 64, y % 64] + else: + orig_color = pixels[x, y][:3] + if orig_color == (0, 0, 0): + out_pixels[x, y] = (0, 0, 0, 255) + elif orig_color in [(128,128,128), (192,192,192)]: + dist_to_grass = 999 + for dy in range(-2, 3): + for dx in range(-2, 3): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'GRASS': + d = math.hypot(dx, dy) + if d < dist_to_grass: + dist_to_grass = d + base_c = orig_color + if dist_to_grass <= 1.5: + shadow = (42, 23, 34, 150) + out_pixels[x, y] = alpha_blend(shadow, base_c) + elif dist_to_grass <= 2.5: + shadow = (42, 23, 34, 70) + out_pixels[x, y] = alpha_blend(shadow, base_c) + else: + out_pixels[x, y] = base_c + (255,) + else: + out_pixels[x, y] = orig_color + (255,) + + # Add flowers and berries to hedges + if basename == 'BMP_1_GRASS_2.png': + add_tiny_flowers(out_pixels, 5, (255, 255, 255, 255), mask, width, height) + elif basename == 'BMP_1_GRASS_3.png': + add_tiny_flowers(out_pixels, 8, (255, 100, 100, 255), mask, width, height) # Red berries + elif basename == 'BMP_1_GRASS_4.png': + add_tiny_flowers(out_pixels, 6, (100, 200, 255, 255), mask, width, height) # Blue berries + + if is_flower: + if 'FLOWER_1' in basename: + draw_large_flower(out_pixels, 32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5, width, height) + elif 'FLOWER_2' in basename: + draw_large_flower(out_pixels, 16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4, width, height) + draw_large_flower(out_pixels, 48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4, width, height) + draw_large_flower(out_pixels, 32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4, width, height) + elif 'FLOWER_3' in basename: + draw_large_flower(out_pixels, 32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6, width, height) + elif 'FLOWER_4' in basename: + draw_large_flower(out_pixels, 32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6, width, height) + + if is_fx: + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + if get_class(px) != 'GRASS' and px not in [(128,128,128), (192,192,192), (0,0,0)]: + out_pixels[x, y] = px + (255,) + + out_img.save(os.path.join(out_dir, basename)) diff --git a/tools/lpc_extract/restyle_v9.py b/tools/lpc_extract/restyle_v9.py new file mode 100644 index 0000000..3987ac6 --- /dev/null +++ b/tools/lpc_extract/restyle_v9.py @@ -0,0 +1,221 @@ +import glob +import os +import random +import math +from PIL import Image + +# Colors for the dense hedge +C_DARK = (37, 86, 46, 255) +C_MED = (70, 130, 50, 255) +C_LIGHT = (92, 154, 42, 255) +C_BRIGHT = (124, 184, 47, 255) +C_SHADOW = (42, 23, 34, 150) +C_SHADOW_SOFT = (42, 23, 34, 70) + +def draw_wrapped_circle(pixels, w, h, cx, cy, r, color): + for y in range(int(cy - r - 1), int(cy + r + 2)): + for x in range(int(cx - r - 1), int(cx + r + 2)): + d = math.hypot(x - cx, y - cy) + if d <= r: + pixels[x % w, y % h] = color + +def generate_seamless_hedge(w, h): + img = Image.new('RGBA', (w, h), C_DARK) + pixels = img.load() + + # Base leaves + for _ in range((w * h) // 16): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(1.0, 2.5), C_MED) + + # Highlights + for _ in range((w * h) // 32): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(1.0, 2.0), C_LIGHT) + + # Bright specks + for _ in range((w * h) // 64): + cx, cy = random.uniform(0, w), random.uniform(0, h) + draw_wrapped_circle(pixels, w, h, cx, cy, random.uniform(0.5, 1.2), C_BRIGHT) + + return img + +def get_class(rgb): + if rgb in [(0, 128, 0), (0, 255, 0)]: + return 'GRASS' + return 'DIRT' + +def alpha_blend(c1, c2): + a = c1[3] / 255.0 + r = int(c1[0] * a + c2[0] * (1 - a)) + g = int(c1[1] * a + c2[1] * (1 - a)) + b = int(c1[2] * a + c2[2] * (1 - a)) + return (r, g, b, 255) + +input_files = glob.glob('/home/enne2/dev/mice/assets/Rat/*BMP_1*.png') +out_dir = '/home/enne2/dev/mice/assets/Rat_LPC_Style/' +os.makedirs(out_dir, exist_ok=True) + +# Generate a single 256x256 seamless base hedge texture to ensure it tiles perfectly across the whole map. +# We will just map it based on (x, y) modulo 256. But since we process individual 64x64 tiles, +# wait, if the game engine places them, it will place different GRASS_X randomly. +# If we want them to tile seamlessly regardless of which one is placed, they must all share the SAME borders! +# So we will use a common 64x64 seamless base texture. +base_hedge_64 = generate_seamless_hedge(64, 64) + +for f in input_files: + basename = os.path.basename(f) + img = Image.open(f).convert('RGBA') + width, height = img.size + pixels = img.load() + + out_img = Image.new('RGBA', (width, height)) + out_pixels = out_img.load() + + is_fx = 'EXPLOSION' in basename or 'GAS' in basename + is_flower = 'FLOWER' in basename + + mask = {} + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + cls = get_class(px) + if is_flower: + mask[(x, y)] = 'GRASS' + elif is_fx: + if cls == 'GRASS': + mask[(x, y)] = 'GRASS' + else: + mask[(x, y)] = 'DIRT' + else: + mask[(x, y)] = cls + + # Make a copy of the base hedge for this specific tile + # so we can add unique interior decorations (flowers/berries) without breaking the seamless border. + tile_hedge = base_hedge_64.copy() + tile_pixels = tile_hedge.load() + + # Add unique variations in the CENTER of the tile (away from edges) so they remain seamless + if basename == 'BMP_1_GRASS_2.png': + # Add red berries in the center + for _ in range(8): + cx, cy = random.randint(16, 48), random.randint(16, 48) + tile_pixels[cx, cy] = (220, 50, 50, 255) + elif basename == 'BMP_1_GRASS_3.png': + # Add white tiny flowers in the center + for _ in range(12): + cx, cy = random.randint(16, 48), random.randint(16, 48) + tile_pixels[cx, cy] = (255, 255, 255, 255) + elif basename == 'BMP_1_GRASS_4.png': + # Add a patch of darker leaves in the center + for _ in range(20): + cx, cy = random.randint(20, 44), random.randint(20, 44) + draw_wrapped_circle(tile_pixels, 64, 64, cx, cy, random.uniform(1.0, 2.5), C_DARK) + + # Apply the mask and borders + for y in range(height): + for x in range(width): + if mask[(x, y)] == 'GRASS': + dist_to_dirt = 999 + for dy in range(-3, 4): + for dx in range(-3, 4): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'DIRT': + d = math.hypot(dx, dy) + if d < dist_to_dirt: + dist_to_dirt = d + + if dist_to_dirt <= 1.5: + dirt_below = (y+1 < height and mask[(x, y+1)] == 'DIRT') or (y+2 < height and mask[(x, y+2)] == 'DIRT') + if dirt_below: + out_pixels[x, y] = C_DARK if (x % 3) == 0 else C_MED + else: + out_pixels[x, y] = C_MED + elif dist_to_dirt <= 2.5: + out_pixels[x, y] = C_LIGHT + else: + out_pixels[x, y] = tile_pixels[x % 64, y % 64] + else: + orig_color = pixels[x, y][:3] + if orig_color == (0, 0, 0): + out_pixels[x, y] = (0, 0, 0, 255) + elif orig_color in [(128,128,128), (192,192,192)]: + dist_to_grass = 999 + for dy in range(-2, 3): + for dx in range(-2, 3): + nx, ny = x + dx, y + dy + if 0 <= nx < width and 0 <= ny < height: + if mask[(nx, ny)] == 'GRASS': + d = math.hypot(dx, dy) + if d < dist_to_grass: + dist_to_grass = d + base_c = orig_color + if dist_to_grass <= 1.5: + out_pixels[x, y] = alpha_blend(C_SHADOW, base_c) + elif dist_to_grass <= 2.5: + out_pixels[x, y] = alpha_blend(C_SHADOW_SOFT, base_c) + else: + out_pixels[x, y] = base_c + (255,) + else: + out_pixels[x, y] = orig_color + (255,) + + # Flowers logic + if is_flower: + def draw_circle(cx, cy, r, color, outline=None): + for fy in range(cy - r - 1, cy + r + 2): + for fx in range(cx - r - 1, cx + r + 2): + if 0 <= fx < width and 0 <= fy < height: + d = math.hypot(fx - cx, fy - cy) + if d <= r: + out_pixels[fx, fy] = color + elif outline and r < d <= r + 1.2: + if out_pixels[fx, fy] != color: + out_pixels[fx, fy] = outline + + def draw_petal(cx, cy, angle, length, pw, color, outline): + cos_a, sin_a = math.cos(angle), math.sin(angle) + size = int(length + pw) + for fy in range(cy - size, cy + size + 1): + for fx in range(cx - size, cx + size + 1): + if 0 <= fx < width and 0 <= fy < height: + dx, dy = fx - cx, fy - cy + rx = dx * cos_a + dy * sin_a + ry = -dx * sin_a + dy * cos_a + if length > 0 and pw > 0: + val = (rx / length)**2 + (ry / pw)**2 + if val <= 1.0: + out_pixels[fx, fy] = color + elif val <= 1.5: + if out_pixels[fx, fy] != color: + out_pixels[fx, fy] = outline + + def draw_large_flower(cx, cy, petal_color, outline_color, center_color, num_petals, petal_length, petal_width): + draw_circle(cx, cy + 3, petal_length + 1, (20, 50, 20, 200)) + for i in range(num_petals): + angle = i * (2 * math.pi / num_petals) + pcolor = (int(petal_color[0]*0.8), int(petal_color[1]*0.8), int(petal_color[2]*0.8), 255) if math.sin(angle) > 0 else petal_color + draw_petal(cx, cy, angle, petal_length, petal_width, pcolor, outline_color) + draw_circle(cx, cy, petal_width + 1, center_color, (int(center_color[0]*0.6), int(center_color[1]*0.6), int(center_color[2]*0.6), 255)) + + if 'FLOWER_1' in basename: + draw_large_flower(32, 32, (240, 240, 240, 255), (100, 100, 110, 255), (240, 200, 50, 255), 10, 14, 5) + elif 'FLOWER_2' in basename: + draw_large_flower(16, 16, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(48, 20, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + draw_large_flower(32, 48, (200, 40, 40, 255), (80, 20, 20, 255), (240, 200, 50, 255), 5, 7, 4) + elif 'FLOWER_3' in basename: + draw_large_flower(32, 32, (220, 80, 180, 255), (100, 30, 80, 255), (240, 200, 50, 255), 8, 12, 6) + elif 'FLOWER_4' in basename: + draw_large_flower(32, 32, (80, 150, 230, 255), (30, 70, 120, 255), (240, 200, 50, 255), 8, 12, 6) + + if is_fx: + for y in range(height): + for x in range(width): + px = pixels[x, y][:3] + if get_class(px) != 'GRASS' and px not in [(128,128,128), (192,192,192), (0,0,0)]: + out_pixels[x, y] = px + (255,) + + out_img.save(os.path.join(out_dir, basename)) + +print("V9 - Procedural organic seamless hedge applied!") diff --git a/tools/lpc_extract/sample_bush.py b/tools/lpc_extract/sample_bush.py new file mode 100644 index 0000000..34f70c0 --- /dev/null +++ b/tools/lpc_extract/sample_bush.py @@ -0,0 +1,14 @@ +from PIL import Image + +img = Image.open('/home/enne2/dev/mice/tools/lpc_extract/bushes.png').convert('RGBA') +pixels = img.load() + +print("Top edge transition:") +for y in range(0, 48): + if pixels[48, y][3] > 0: + print(f"y={y}: {pixels[48, y]}") + +print("\nBottom edge transition:") +for y in range(95, 48, -1): + if pixels[48, y][3] > 0: + print(f"y={y}: {pixels[48, y]}") diff --git a/tools/lpc_extract/solve_grass.py b/tools/lpc_extract/solve_grass.py new file mode 100644 index 0000000..58e0ba9 --- /dev/null +++ b/tools/lpc_extract/solve_grass.py @@ -0,0 +1,22 @@ +from PIL import Image + +src_img = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') + +# The plain grass tile in LPC terrain is typically at col 4, row 1 (0-indexed) +tx, ty = 4, 1 +box = (tx * 32, ty * 32, (tx + 1) * 32, (ty + 1) * 32) +tile32 = src_img.crop(box) + +# Strategy 1: Tile it 2x2 to make a 64x64 image +img_tiled = Image.new('RGBA', (64, 64)) +img_tiled.paste(tile32, (0, 0)) +img_tiled.paste(tile32, (32, 0)) +img_tiled.paste(tile32, (0, 32)) +img_tiled.paste(tile32, (32, 32)) +img_tiled.save('/home/enne2/dev/mice/tools/lpc_extract/BMP_1_GRASS_1_tiled.png') + +# Strategy 2: Scale it 2x to make a 64x64 image +img_scaled = tile32.resize((64, 64), Image.NEAREST) +img_scaled.save('/home/enne2/dev/mice/tools/lpc_extract/BMP_1_GRASS_1_scaled.png') + +print("Created BMP_1_GRASS_1_tiled.png and BMP_1_GRASS_1_scaled.png") diff --git a/tools/lpc_extract/test_hedge.py b/tools/lpc_extract/test_hedge.py new file mode 100644 index 0000000..68d9c7c --- /dev/null +++ b/tools/lpc_extract/test_hedge.py @@ -0,0 +1,4 @@ +import sys +from PIL import Image +lpc = Image.open('/home/enne2/dev/asset-maker/assets/poses/sources/lpc-revised/Terrain/terrain_spring.png').convert('RGBA') +lpc.crop((0, 0, 96, 96)).save('/home/enne2/dev/mice/tools/lpc_extract/bushes.png') diff --git a/units/rat.py b/units/rat.py index 5c26107..e680bf0 100644 --- a/units/rat.py +++ b/units/rat.py @@ -195,8 +195,9 @@ class Rat(Unit): if not self.game.map.is_empty(cell_x, cell_y): return - # Use pre-calculated positions - self.game.render_engine.draw_image(self.render_x, self.render_y, image, anchor="nw", tag="unit") + frame = min(3, int(self.partial_move * 4)) + source_rect = (frame * image_size[0], 0, image_size[0], image_size[1]) + self.game.render_engine.draw_image(self.render_x, self.render_y, image, anchor="nw", tag="unit", source_rect=source_rect) # bbox already updated in _update_render_position() #self.game.render_engine.draw_rectangle(self.bbox[0], self.bbox[1], self.bbox[2] - self.bbox[0], self.bbox[3] - self.bbox[1], "unit") @@ -215,13 +216,16 @@ class Rat(Unit): if width <= 0 or height <= 0: return False + frame = min(3, int(self.partial_move * 4)) + actual_source_x = source_x + (frame * image_size[0]) + self.game.render_engine.draw_image( self.render_x if draw_x is None else draw_x, self.render_y if draw_y is None else draw_y, image, anchor="nw", tag="unit", - source_rect=(source_x, source_y, width, height), + source_rect=(actual_source_x, source_y, width, height), dest_size=(width, height), ) return True