Pārlūkot izejas kodu

Merge key_copier from https://github.com/xMasterX/all-the-plugins

# Conflicts:
#	key_copier/application.fam
#	key_copier/key_formats.c
Willy-JL 1 gadu atpakaļ
vecāks
revīzija
d5a86f85b4

+ 1 - 1
key_copier/.gitsubtree

@@ -1,2 +1,2 @@
-https://github.com/xMasterX/all-the-plugins dev non_catalog_apps/key_copier 4558d74c9da36abc851edd96a95d18f7d5511a75
+https://github.com/xMasterX/all-the-plugins dev non_catalog_apps/key_copier ffa18100afc128abea7269fcc31d9c237523e7c6
 https://github.com/zinongli/KeyCopier main /

+ 27 - 0
key_copier/CHANGELOG.md

@@ -1,3 +1,30 @@
+## 1.1
+## What's Changed
+* Support for double sided key and multiple new key formats by @HonestLocksmith
+* New formats:
+Manufacturer-Format Name-Data Sheet(if applicable)
+Arrow-AR4-C2
+Master Lock-M1-C35
+American-AM7-C80
+Yale-Y2-.025
+Yale-Y11-CX55
+Sargent-S22-C44
+National-NA25-C40
+Corbin-CO88-C14
+Lockwood-LW4
+Lockwood-LW5
+National-NA12-C39
+Russwin-RU45-CX6
+Ford-H75-CX101
+Chevrolet-B102
+Dodge-Y159-CX102
+Kawasaki-KA14-CMC50
+Yamaha-YM63-CMC71
+Best (A2)-SFIC-C3
+RV (FIC,GL,Bauer)-RV
+
+Thank you @HonestLocksmith!
+
 ## 1.0
 - Initial release.
 - Supports measuring, saving, and loading keys with .keycopy extension.

+ 2 - 0
key_copier/README.md

@@ -9,7 +9,9 @@ To measure your key:
 
 ## Special Thanks
 - Thank [@jamisonderek](https://github.com/jamisonderek) for his [Flipper Zero Tutorial repository](https://github.com/jamisonderek/flipper-zero-tutorials) and [YouTube channel](https://github.com/jamisonderek/flipper-zero-tutorials#:~:text=YouTube%3A%20%40MrDerekJamison)! This app is built with his Skeleton App and GPIO Wiegand app as references. 
+- Thank [@HonestLocksmith](https://github.com/HonestLocksmith) for PR #13 and #20. TONS of new key formats and supports for DOUBLE-SIDED keys are added. We have car keys now! 
 - [Project channel](https://discord.com/channels/1112390971250974782/1264067969634402356)
 
 
 
+

+ 1 - 1
key_copier/application.fam

@@ -12,6 +12,6 @@ App(
     fap_category="Tools",
     fap_icon_assets="assets",
     fap_description="@README.md",
-    fap_version="1.0",
+    fap_version="1.1",
     fap_author="Torron",
 )

+ 154 - 31
key_copier/key_copier.c

@@ -1,22 +1,23 @@
+#include "key_copier.h"
+#include "key_copier_icons.h"
+#include "key_formats.h"
+#include <applications/services/dialogs/dialogs.h>
+#include <applications/services/storage/storage.h>
+#include <flipper_format.h>
 #include <furi.h>
 #include <furi_hal.h>
 #include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/view_dispatcher.h>
 #include <gui/modules/submenu.h>
 #include <gui/modules/text_input.h>
-#include <gui/modules/widget.h>
 #include <gui/modules/variable_item_list.h>
+#include <gui/modules/widget.h>
+#include <gui/view.h>
+#include <gui/view_dispatcher.h>
+#include <math.h>
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
-#include <applications/services/storage/storage.h>
-#include <applications/services/dialogs/dialogs.h>
 #include <stdbool.h>
-#include <math.h>
-#include <flipper_format.h>
-#include "key_copier_icons.h"
-#include "key_formats.h"
-#include "key_copier.h"
+
 #define TAG "KeyCopier"
 
 #define BACKLIGHT_ON 1
@@ -166,9 +167,11 @@ static void key_copier_config_enter_callback(void* context) {
     key_copier_format_change(app->format_item);
     view_set_previous_callback(view_config_i, key_copier_navigation_submenu_callback);
     view_dispatcher_remove_view(
-        app->view_dispatcher, KeyCopierViewConfigure_i); // delete the last one
+        app->view_dispatcher,
+        KeyCopierViewConfigure_i); // delete the last one
     view_dispatcher_add_view(app->view_dispatcher, KeyCopierViewConfigure_i, view_config_i);
-    view_dispatcher_switch_to_view(app->view_dispatcher, KeyCopierViewConfigure_i); // recreate it
+    view_dispatcher_switch_to_view(app->view_dispatcher,
+                                   KeyCopierViewConfigure_i); // recreate it
 }
 
 static const char* key_name_entry_text = "Enter name";
@@ -250,7 +253,8 @@ static void key_copier_view_save_callback(void* context) {
         },
         redraw);
 
-    // Configure the text input.  When user enters text and clicks OK, key_copier_file_saver be called.
+    // Configure the text input.  When user enters text and clicks OK,
+    // key_copier_file_saver be called.
     bool clear_previous_text = false;
     text_input_set_result_callback(
         app->text_input,
@@ -316,9 +320,18 @@ static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
     double drill_radians =
         (180 - my_format.drill_angle) / 2 / 180 * (double)M_PI; // Convert angle to radians
     double tangent = tan(drill_radians);
-    int top_contour_px = (int)round(63 - my_format.uncut_depth_inch / inches_per_px);
+    int top_contour_px = (int)round(62 - my_format.uncut_depth_inch / inches_per_px);
+    int bottom_contour_px = 0;
+
+    if(my_format.sides == 2)
+        bottom_contour_px =
+            top_contour_px + (int)round(my_format.uncut_depth_inch / inches_per_px);
     int post_extra_x_px = 0;
     int pre_extra_x_px = 0;
+    int bottom_post_extra_x_px = 0; // new
+    int bottom_pre_extra_x_px = 0; // new
+    int level_contour_px =
+    (int)round((my_format.last_pin_inch + my_format.elbow_inch) / inches_per_px);
     for(int current_pin = 1; current_pin <= my_model->format.pin_num; current_pin += 1) {
         double current_center_px =
             my_format.first_pin_inch + (current_pin - 1) * my_format.pin_increment_inch;
@@ -347,7 +360,98 @@ static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
             pin_center_px - pin_half_width_px,
             top_contour_px + current_depth_px,
             pin_center_px + pin_half_width_px,
-            top_contour_px + current_depth_px); // draw pin width horizontal line
+            top_contour_px + current_depth_px); // draw top pin width horizontal line
+
+        if(my_format.sides == 2) { // new
+            int last_depth = my_model->depth[current_pin - 2] - my_format.min_depth_ind;
+            int next_depth = my_model->depth[current_pin] - my_format.min_depth_ind;
+            int current_depth = my_model->depth[current_pin - 1] - my_format.min_depth_ind;
+            int current_depth_px =
+                (int)round(current_depth * my_format.depth_step_inch / inches_per_px);
+
+            // Draw horizontal line for bottom pin
+            canvas_draw_line(
+                canvas,
+                pin_center_px - pin_half_width_px,
+                bottom_contour_px - current_depth_px,
+                pin_center_px + pin_half_width_px,
+                bottom_contour_px - current_depth_px);
+
+            // Handle first pin for bottom
+            if(current_pin == 1) {
+                canvas_draw_line(
+                    canvas,
+                    0,
+                    bottom_contour_px,
+                    pin_center_px - pin_half_width_px - current_depth_px,
+                    bottom_contour_px);
+                last_depth = 0;
+                bottom_pre_extra_x_px = max(current_depth_px + pin_half_width_px, 0);
+            }
+
+            // Handle left side intersection for bottom
+            if((last_depth + current_depth) > my_format.clearance) {
+                if(current_pin != 1) {
+                    bottom_pre_extra_x_px =
+                        min(max(pin_step_px - bottom_post_extra_x_px, pin_half_width_px),
+                            pin_step_px - pin_half_width_px);
+                }
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px - bottom_pre_extra_x_px,
+                    bottom_contour_px -
+                        max((int)round(
+                                (current_depth_px - (bottom_pre_extra_x_px - pin_half_width_px)) *
+                                tangent),
+                            0),
+                    pin_center_px - pin_half_width_px,
+                    bottom_contour_px - (int)round(current_depth_px * tangent));
+            } else {
+                int last_depth_px =
+                    (int)round(last_depth * my_format.depth_step_inch / inches_per_px);
+                int up_slope_start_x_px = pin_center_px - pin_half_width_px - current_depth_px;
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px - pin_half_width_px - current_depth_px,
+                    bottom_contour_px,
+                    pin_center_px - pin_half_width_px,
+                    bottom_contour_px - (int)round(current_depth_px * tangent));
+                canvas_draw_line(
+                    canvas,
+                    min(pin_center_px - pin_step_px + pin_half_width_px + last_depth_px,
+                        up_slope_start_x_px),
+                    bottom_contour_px,
+                    up_slope_start_x_px,
+                    bottom_contour_px);
+            }
+
+            // Handle right side intersection for bottom
+            if((current_depth + next_depth) > my_format.clearance) {
+                double numerator = (double)current_depth;
+                double denominator = (double)(current_depth + next_depth);
+                double product = (numerator / denominator) * pin_step_px;
+                bottom_post_extra_x_px =
+                    (int)min(max(product, pin_half_width_px), pin_step_px - pin_half_width_px);
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px + pin_half_width_px,
+                    bottom_contour_px - current_depth_px,
+                    pin_center_px + bottom_post_extra_x_px,
+                    bottom_contour_px -
+                        max(current_depth_px -
+                                (int)round((bottom_post_extra_x_px - pin_half_width_px) * tangent),
+                            0));
+            } else {
+                canvas_draw_line(
+                    canvas,
+                    pin_center_px + pin_half_width_px,
+                    bottom_contour_px - (int)round(current_depth_px * tangent),
+                    pin_center_px + pin_half_width_px + current_depth_px,
+                    bottom_contour_px);
+            }
+        }
+        // new end
+
         int last_depth = my_model->depth[current_pin - 2] - my_format.min_depth_ind;
         int next_depth = my_model->depth[current_pin] - my_format.min_depth_ind;
         if(current_pin == 1) {
@@ -356,14 +460,25 @@ static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
                 0,
                 top_contour_px,
                 pin_center_px - pin_half_width_px - current_depth_px,
-                top_contour_px);
+                top_contour_px); // draw top shoulder
             last_depth = 0;
             pre_extra_x_px = max(current_depth_px + pin_half_width_px, 0);
+            if(my_format.sides == 2) {
+                canvas_draw_line(
+                    canvas,
+                    0,
+                    bottom_contour_px,
+                    pin_center_px - pin_half_width_px - current_depth_px,
+                    bottom_contour_px); // draw bottom shoulder (hidden by level contour)
+            } else {
+                canvas_draw_line(canvas, 0, 62, level_contour_px, 62);
+            }
         }
         if(current_pin == my_model->format.pin_num) {
             next_depth = 0;
         }
-        if((last_depth + current_depth) > my_format.clearance) { //yes intersection
+        if((last_depth + current_depth) > my_format.clearance) { // yes
+            // intersection
 
             if(current_pin != 1) {
                 pre_extra_x_px =
@@ -396,7 +511,8 @@ static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
                 down_slope_start_x_px,
                 top_contour_px);
         }
-        if((current_depth + next_depth) > my_format.clearance) { //yes intersection
+        if((current_depth + next_depth) > my_format.clearance) { // yes
+            // intersection
             double numerator = (double)current_depth;
             double denominator = (double)(current_depth + next_depth);
             double product = (numerator / denominator) * pin_step_px;
@@ -421,11 +537,16 @@ static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
         }
     }
 
-    int level_contour_px =
-        (int)round((my_format.last_pin_inch + my_format.elbow_inch) / inches_per_px);
     int elbow_px = (int)round(my_format.elbow_inch / inches_per_px);
-    canvas_draw_line(canvas, 0, 62, level_contour_px, 62);
     canvas_draw_line(canvas, level_contour_px, 62, level_contour_px + elbow_px, 62 - elbow_px);
+    canvas_draw_line(canvas, 0, top_contour_px - 6, 0, top_contour_px);
+    if(my_format.stop == 2) {
+        // Draw a line using level_contour_px if stop equals 2 elbow must be firt pin inch
+        canvas_draw_line(canvas, level_contour_px, top_contour_px, level_contour_px, 63);
+        //  } else {
+        // Otherwise, draw a default line
+        //    canvas_draw_line(canvas, 0, top_contour_px, 0, 63); // too confusing but may want later
+    }
 
     int slc_pin_px = (int)round(
         (my_format.first_pin_inch + (my_model->pin_slc - 1) * my_format.pin_increment_inch) /
@@ -433,7 +554,7 @@ static void key_copier_view_measure_draw_callback(Canvas* canvas, void* model) {
     canvas_draw_icon(canvas, slc_pin_px - 2, top_contour_px - 25, &I_arrow_down);
 
     furi_string_printf(buffer, "%s", my_format.format_name);
-    canvas_draw_str(canvas, 110, 10, furi_string_get_cstr(buffer));
+    canvas_draw_str(canvas, 100, 10, furi_string_get_cstr(buffer));
     furi_string_free(buffer);
 }
 
@@ -474,13 +595,12 @@ static bool key_copier_view_measure_input_callback(InputEvent* event, void* cont
                 KeyCopierModel * model,
                 {
                     if(model->depth[model->pin_slc - 1] > model->format.min_depth_ind) {
-                        if(model->pin_slc == 1) { //first pin only limited by the next one
+                        if(model->pin_slc == 1) { // first pin only limited by the next one
                             if(model->depth[model->pin_slc] - model->depth[model->pin_slc - 1] <
                                model->format.macs)
                                 model->depth[model->pin_slc - 1]--;
-                        } else if(
-                            model->pin_slc ==
-                            model->format.pin_num) { //last pin only limited by the previous one
+                        } else if(model->pin_slc == model->format.pin_num) { // last pin only limited by
+                            // the previous one
                             if(model->depth[model->pin_slc - 2] -
                                    model->depth[model->pin_slc - 1] <
                                model->format.macs) {
@@ -507,13 +627,12 @@ static bool key_copier_view_measure_input_callback(InputEvent* event, void* cont
                 KeyCopierModel * model,
                 {
                     if(model->depth[model->pin_slc - 1] < model->format.max_depth_ind) {
-                        if(model->pin_slc == 1) { //first pin only limited by the next one
+                        if(model->pin_slc == 1) { // first pin only limited by the next one
                             if(model->depth[model->pin_slc - 1] - model->depth[model->pin_slc] <
                                model->format.macs)
                                 model->depth[model->pin_slc - 1]++;
-                        } else if(
-                            model->pin_slc ==
-                            model->format.pin_num) { //last pin only limited by the previous one
+                        } else if(model->pin_slc == model->format.pin_num) { // last pin only limited by
+                            // the previous one
                             if(model->depth[model->pin_slc - 1] -
                                    model->depth[model->pin_slc - 2] <
                                model->format.macs) {
@@ -616,7 +735,11 @@ static KeyCopierApp* key_copier_app_alloc() {
         0,
         128,
         64,
-        "Key Maker App 1.0\nAuthor: @Torron\n\nTo measure your key:\n\n1. Place it on top of the screen.\n\n2. Use the contour to align your key.\n\n3. Adjust each pin's depth until they match. It's easier if you look with one eye closed.\n\nGithub: github.com/zinongli/KeyCopier \n\nSpecial thanks to Derek Jamison's Skeleton App Template.");
+        "Key Maker App 1.1\nAuthor: @Torron\n\nTo measure your key:\n\n1. Place "
+        "it on top of the screen.\n\n2. Use the contour to align your key.\n\n3. "
+        "Adjust each pin's depth until they match. It's easier if you look with "
+        "one eye closed.\n\nGithub: github.com/zinongli/KeyCopier \n\nSpecial "
+        "thanks to Derek Jamison's Skeleton App Template.");
     view_set_previous_callback(
         widget_get_view(app->widget_about), key_copier_navigation_submenu_callback);
     view_dispatcher_add_view(

+ 362 - 3
key_copier/key_formats.c

@@ -29,12 +29,371 @@ const KeyFormat all_formats[] = {
      .pin_num = 6,
      .pin_width_inch = 0.031,
      .elbow_inch = 0.1,
-     .drill_angle =
-         90, // This should actually be 100 but the current resolution will make 100 degrees very ugly and unsuable
+     .drill_angle = 90, // This should actually be 100 but the current resolution will make
+     // 100 degrees very ugly and unsuable
      .uncut_depth_inch = 0.335,
      .deepest_depth_inch = 0.2,
      .depth_step_inch = 0.015,
      .min_depth_ind = 0,
      .max_depth_ind = 9,
      .macs = 7,
-     .clearance = 8}};
+     .clearance = 8},
+
+    {.manufacturer = "Arrow",
+     .format_name = "AR4",
+     .format_link = "C2",
+     .first_pin_inch = 0.265,
+     .last_pin_inch = 1.040,
+     .pin_increment_inch = 0.155,
+     .pin_num = 6,
+     .pin_width_inch = 0.060,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.312,
+     .deepest_depth_inch = 0.186,
+     .depth_step_inch = 0.014,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 6,
+     .clearance = 7},
+
+    {.manufacturer = "Master Lock",
+     .format_name = "M1",
+     .format_link = "C35",
+     .first_pin_inch = 0.185,
+     .last_pin_inch = 0.689,
+     .pin_increment_inch = 0.126,
+     .pin_num = 5,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.276,
+     .deepest_depth_inch = 0.171,
+     .depth_step_inch = 0.015,
+     .min_depth_ind = 0,
+     .max_depth_ind = 7,
+     .macs = 7,
+     .clearance = 6},
+
+    {.manufacturer = "American",
+     .format_name = "AM7",
+     .format_link = "C80",
+     .first_pin_inch = 0.157,
+     .last_pin_inch = 0.781,
+     .pin_increment_inch = 0.125,
+     .pin_num = 6,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.283,
+     .deepest_depth_inch = 0.173,
+     .depth_step_inch = 0.016,
+     .min_depth_ind = 1,
+     .max_depth_ind = 8,
+     .macs = 7,
+     .clearance = 5},
+
+    {.manufacturer = "Yale",
+     .format_name = "Y2",
+     .format_link = "C57",
+     .first_pin_inch = 0.200,
+     .last_pin_inch = 1.025,
+     .pin_increment_inch = 0.165,
+     .pin_num = 6,
+     .pin_width_inch = 0.054,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.320,
+     .deepest_depth_inch = 0.149,
+     .depth_step_inch = 0.019,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 9,
+     .clearance = 4},
+
+    {.manufacturer = "Yale",
+     .format_name = "Y11",
+     .format_link = "CX55",
+     .first_pin_inch = 0.124,
+     .last_pin_inch = 0.502,
+     .pin_increment_inch = 0.095,
+     .pin_num = 5,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.246,
+     .deepest_depth_inch = 0.167,
+     .depth_step_inch = 0.020,
+     .min_depth_ind = 1,
+     .max_depth_ind = 5,
+     .macs = 7,
+     .clearance = 3},
+
+    {.manufacturer = "Sargent",
+     .format_name = "S22",
+     .format_link = "C44",
+     .first_pin_inch = 0.216,
+     .last_pin_inch = 0.996,
+     .pin_increment_inch = 0.156,
+     .pin_num = 6,
+     .pin_width_inch = 0.063,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.328, // double check
+     .deepest_depth_inch = 0.148,
+     .depth_step_inch = 0.020,
+     .min_depth_ind = 1,
+     .max_depth_ind = 10,
+     .macs = 7,
+     .clearance = 5},
+
+    {.manufacturer = "National",
+     .format_name = "NA25",
+     .format_link = "C40",
+     .first_pin_inch = 0.250,
+     .last_pin_inch = 0.874,
+     .pin_increment_inch = 0.156,
+     .pin_num = 5,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.304,
+     .deepest_depth_inch = 0.191,
+     .depth_step_inch = 0.012,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 7,
+     .clearance = 8},
+
+    {.manufacturer = "Corbin",
+     .format_name = "CO88",
+     .format_link = "C14",
+     .first_pin_inch = 0.250,
+     .last_pin_inch = 1.030,
+     .pin_increment_inch = 0.156,
+     .pin_num = 6,
+     .pin_width_inch = 0.047,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.343,
+     .deepest_depth_inch = 0.217,
+     .depth_step_inch = 0.014,
+     .min_depth_ind = 1,
+     .max_depth_ind = 10,
+     .macs = 7,
+     .clearance = 8},
+
+    {.manufacturer = "Lockwood",
+     .format_name = "LW4",
+     .format_link = "",
+     .first_pin_inch = 0.245,
+     .last_pin_inch = 0.870,
+     .pin_increment_inch = 0.1562,
+     .pin_num = 5,
+     .pin_width_inch = 0.031,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.344,
+     .deepest_depth_inch = 0.203,
+     .depth_step_inch = 0.014,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 9,
+     .clearance = 8},
+
+    {.manufacturer = "Lockwood",
+     .format_name = "LW5",
+     .format_link = "",
+     .first_pin_inch = 0.245,
+     .last_pin_inch = 1.0262,
+     .pin_increment_inch = 0.1562,
+     .pin_num = 6,
+     .pin_width_inch = 0.031,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.344,
+     .deepest_depth_inch = 0.203,
+     .depth_step_inch = 0.014,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 9,
+     .clearance = 8},
+
+    {.manufacturer = "National",
+     .format_name = "NA12",
+     .format_link = "C39",
+     .first_pin_inch = 0.150,
+     .last_pin_inch = 0.710,
+     .pin_increment_inch = 0.140,
+     .pin_num = 5,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.270,
+     .deepest_depth_inch = 0.157,
+     .depth_step_inch = 0.013,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 7,
+     .clearance = 8},
+
+    {.manufacturer = "Russwin",
+     .format_name = "RU45",
+     .format_link = "CX6",
+     .first_pin_inch = 0.250,
+     .last_pin_inch = 1.030,
+     .pin_increment_inch = 0.156,
+     .pin_num = 6,
+     .pin_width_inch = 0.053,
+     .elbow_inch = 0.1,
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.343,
+     .deepest_depth_inch = 0.203,
+     .depth_step_inch = 0.028,
+     .min_depth_ind = 1,
+     .max_depth_ind = 6,
+     .macs = 5,
+     .clearance = 3},
+
+    {.manufacturer = "Ford",
+     .format_name = "H75",
+     .sides = 2,
+     .stop = 2,
+     .format_link = "CX101",
+     .first_pin_inch = 0.201,
+     .last_pin_inch = 0.845,
+     .pin_increment_inch = 0.092,
+     .pin_num = 8,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.201, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.354,
+     .deepest_depth_inch = 0.254,
+     .depth_step_inch = 0.025,
+     .min_depth_ind = 1,
+     .max_depth_ind = 5,
+     .macs = 5,
+     .clearance = 2},
+
+    {.manufacturer = "Chevrolet",
+     .format_name = "B102",
+     .sides = 2,
+     .stop = 2,
+     .format_link = "",
+     .first_pin_inch = 0.205,
+     .last_pin_inch = 1.037,
+     .pin_increment_inch = 0.093,
+     .pin_num = 10,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.205, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.315,
+     .deepest_depth_inch = 0.161,
+     .depth_step_inch = 0.026,
+     .min_depth_ind = 1,
+     .max_depth_ind = 4,
+     .macs = 5,
+     .clearance = 2},
+
+    {.manufacturer = "Dodge",
+     .format_name = "Y159",
+     .sides = 2,
+     .stop = 2,
+     .format_link = "CX102",
+     .first_pin_inch = 0.297,
+     .last_pin_inch = 0.941,
+     .pin_increment_inch = 0.092,
+     .pin_num = 8,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.297, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.339,
+     .deepest_depth_inch = 0.197,
+     .depth_step_inch = 0.047,
+     .min_depth_ind = 1,
+     .max_depth_ind = 4,
+     .macs = 5,
+     .clearance = 1},
+
+    {.manufacturer = "Kawasaki",
+     .format_name = "KA14",
+     .sides = 2,
+     .format_link = "CMC50",
+     .first_pin_inch = 0.098,
+     .last_pin_inch = 0.591,
+     .pin_increment_inch = 0.098,
+     .pin_num = 6,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.258,
+     .deepest_depth_inch = 0.198,
+     .depth_step_inch = 0.020,
+     .min_depth_ind = 1,
+     .max_depth_ind = 4,
+     .macs = 4,
+     .clearance = 3},
+
+    {.manufacturer = "Yamaha",
+     .format_name = "YM63",
+     .sides = 2,
+     .format_link = "CMC71",
+     .first_pin_inch = 0.157,
+     .last_pin_inch = 0.748,
+     .pin_increment_inch = 0.098,
+     .pin_num = 7,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.1, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.295,
+     .deepest_depth_inch = 0.236,
+     .depth_step_inch = 0.020,
+     .min_depth_ind = 1,
+     .max_depth_ind = 4,
+     .macs = 4,
+     .clearance = 3},
+
+    {.manufacturer = "Best (A2)",
+     .format_name = "SFIC",
+     .stop = 2,
+     .format_link = "C3",
+     .first_pin_inch = 0.250,
+     .last_pin_inch = 0.998,
+     .pin_increment_inch = 0.149,
+     .pin_num = 6,
+     .pin_width_inch = 0.051,
+     .elbow_inch = 0.081, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.318,
+     .deepest_depth_inch = 0.206,
+     .depth_step_inch = 0.025,
+     .min_depth_ind = 0,
+     .max_depth_ind = 9,
+     .macs = 5,
+     .clearance = 3},
+
+    {.manufacturer = "RV (FIC,GL,Bauer)",
+     .format_name = "RV",
+     .sides = 2,
+     .format_link = "Card",
+     .first_pin_inch = 0.126,
+     .last_pin_inch = 0.504,
+     .pin_increment_inch = 0.094,
+     .pin_num = 5,
+     .pin_width_inch = 0.039,
+     .elbow_inch = 0.126, // this should be equal to first pin inch for tip
+     // stopped key line
+     .drill_angle = 90,
+     .uncut_depth_inch = 0.260,
+     .deepest_depth_inch = 0.181,
+     .depth_step_inch = 0.040,
+     .min_depth_ind = 1,
+     .max_depth_ind = 3,
+     .macs = 3,
+     .clearance = 1}};

+ 3 - 2
key_copier/key_formats.h

@@ -1,13 +1,14 @@
 #ifndef KEY_FORMATS_H
 #define KEY_FORMATS_H
 
-#define FORMAT_NUM 2
+#define FORMAT_NUM 21
 
 typedef struct {
     char* manufacturer;
     char* format_name;
     char* format_link;
-
+    int sides;
+    int stop;
     double first_pin_inch;
     double last_pin_inch;
     double pin_increment_inch;