{"id":20785385,"url":"https://github.com/o-murphy/bcrg","last_synced_at":"2025-12-24T17:35:40.148Z","repository":{"id":241855020,"uuid":"807617884","full_name":"o-murphy/bcrg","owner":"o-murphy","description":"Simple lua-based engine to generate dynamic ballistics reticles","archived":false,"fork":false,"pushed_at":"2025-09-16T19:43:58.000Z","size":94,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-16T22:12:12.504Z","etag":null,"topics":["ballistics","framebuf","lua","luascript","python","python3","reticles"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/bcrg","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/o-murphy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-29T12:54:21.000Z","updated_at":"2025-09-16T19:44:02.000Z","dependencies_parsed_at":"2024-08-08T16:15:38.413Z","dependency_job_id":"0131680e-9ee4-4baf-877d-ece5bf462497","html_url":"https://github.com/o-murphy/bcrg","commit_stats":null,"previous_names":["o-murphy/bcrg"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/o-murphy/bcrg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fbcrg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fbcrg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fbcrg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fbcrg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/o-murphy","download_url":"https://codeload.github.com/o-murphy/bcrg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-murphy%2Fbcrg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276641326,"owners_count":25678527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-23T02:00:09.130Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ballistics","framebuf","lua","luascript","python","python3","reticles"],"created_at":"2024-11-17T14:45:19.862Z","updated_at":"2025-12-24T17:35:40.141Z","avatar_url":"https://github.com/o-murphy.png","language":"Lua","readme":"# BCRG - Ballistic reticle generator\n\n### Simple tool to generate dynamic ballistics reticles by .lua templates\n\n[\u003cimg src=\"https://flagicons.lipis.dev/flags/4x3/ua.svg\" width=\"20\"/\u003e **Українською**](./README.ua.md)\n\n-----\n\n## Installation 🚀\n\nInstall the **BCRG** ballistic reticle generator using `pip` (the standard method) or the newer **`uv`** tool (recommended for speed and efficiency).\n\n### Using uv (Recommended)\n\nIf you have the **uv** tool installed, you can manage the package directly:\n\n**Installation:**\n\n```bash\nuv tool install bcrg\n```\n\n**Upgrade:**\n\n```bash\nuv tool upgrade bcrg\n```\n\n### Using pip (Standard Method)\n\nIf you are using the standard Python package manager:\n\n**Installation:**\n\n```bash\npip install bcrg\n```\n\n**Upgrade:**\n\n```bash\npip install --upgrade bcrg\n```\n\n-----\n\n## Usage\n\n### As CLI tool (Via Command Line)\n\nUse `bcrg` or `python -m bcrg` to generate reticle images (BMP) from Lua templates:\n\n```bash\nusage: bcr [-h] [-o OUTPUT] [-f] [-W \u003cint\u003e] [-H \u003cint\u003e] [-cx \u003cfloat\u003e] [-cy \u003cfloat\u003e] [-z [\u003cint\u003e ...]] [-T | -Z] file\n\npositional arguments:\n  file                  Reticle template file in .lua format\n\noptions:\n  -h, --help            show this help message and exit\n  -o OUTPUT, --output OUTPUT\n                        Output directory path, defaults to ./\n  -f, --force           Force overwrite existing files without prompt\n  -W \u003cint\u003e, --width \u003cint\u003e\n                        Canvas width (px)\n  -H \u003cint\u003e, --height \u003cint\u003e\n                        Canvas height (px)\n  -cx \u003cfloat\u003e, --click-x \u003cfloat\u003e\n                        Horizontal click size (cm/100m)\n  -cy \u003cfloat\u003e, --click-y \u003cfloat\u003e\n                        Vertical click size (cm/100m)\n  -z [\u003cint\u003e ...], --zoom [\u003cint\u003e ...]\n                        Zoom value (int)\n  -V, --version         show program\\'s version number and exit\n  \narchiving options:\n  -T, --tar             Store as .tar.gz (overrides --zip)\n  -Z, --zip             Store as .zip\n```\n\n### As Imported module\n\nYou can integrate the generator directly into your Python code:\n\n```python\nfrom bcrg import LuaReticleLoader\nloader = LuaReticleLoader('my_reticle_template.lua')\n\n# Create 1bit-depth .bmp bytearray\n# Parameters: width, height, click_x, click_y, zoom, adjustment\nbyte_stream = loader.make_bmp(640, 480, 2.27, 2.27, 4, None)\nwith open(\"myreticle.bmp\", 'wb') as f:\n    f.write(byte_stream)\n```\n\n### References\n\n  * A reticle template has to implement `make_reticle` function, that gets required arguments and has to return `self:to_bmp` or `self:to_bmp_1bit`.\n  * Examples in `./templates` dir.\n\n-----\n\n## 📐 Reticle Template API (Lua)\n\nThis section details how to create Lua templates using the **ReticleDraw** library, which extends **`FrameBuffer`**.\n\n### 🛠️ Reticle File Structure and `make_reticle`\n\nEvery reticle file must declare a dependency on `reticledraw`\n\n```lua\n-- Load the framebuffer module\nrequire(\"reticledraw\") -- 👈 THIS LINE IS CRUCIAL!\n```\n\nEvery reticle file must contain a single `make_reticle` function.\n\n```lua\nfunction make_reticle(width, height, click_x, click_y, zoom, adjustment)\n    -- ... Your drawing code ...\nend\n```\n\n| Parameter | Type | Description |\n| :--- | :--- | :--- |\n| **`width`** | `number` | Framebuffer (display) width in pixels. |\n| **`height`** | `number` | Framebuffer (display) height in pixels. |\n| **`click_x`** | `number` | **Click Value (Correction Value)** on the X-axis (e.g., MILs/MOAs per pixel at *minimum* zoom). |\n| **`click_y`** | `number` | **Click Value (Correction Value)** on the Y-axis. |\n| **`zoom`** | `number` | Current scope **magnification** (zoom value). |\n| **`adjustment`** | `table` | Optional additional reticle parameters/settings. |\n\n### 🚀 General Code Template and Scaling Logic (With Examples)\n\nThe core logic converts **reticle units** (MILs/MOAs) into **screen pixels** using the scaling coefficients `ax` and `ay`.\n\n```lua\nrequire(\"reticledraw\")\n\nlocal BLACK = 0\nlocal WHITE = 1\n\n-- Rounding function (ensures the pixel value is an integer)\nlocal function round(v)\n    if v \u003c 0 then\n        return math.ceil(v)\n    elseif v \u003e 0 then\n        return math.floor(v)\n    else\n        return 0\n    end\nend\n\nfunction make_reticle(width, height, click_x, click_y, zoom, adjustment)\n    -- 1. Calculate scaling coefficients (AX, AY)\n    -- AX/AY: how many reticle units correspond to 1 pixel on the screen at the current ZOOM.\n    local ax = click_x / zoom\n    local ay = click_y / zoom\n\n    -- 2. Helper functions: convert reticle units (v) to pixels\n    local function _x(v)\n        return round(v / ax)\n    end\n    local function _y(v)\n        return round(v / ay)\n    end\n\n    local fb = make_canvas(width, height, 1)\n    fb:fill(WHITE)\n\n    -- 3. Examples of drawing reticle elements:\n\n    -- Center dot (3x3 pixels)\n    fb:c_fill_rect(0, 0, 3, 3, BLACK) \n\n    -- Main horizontal line (from -100 to +100 units)\n    fb:c_line(_x(-100), 0, _x(100), 0, BLACK) \n    \n    -- Dynamic markers: drawing lines every 10 units\n    local marker_length = 5 -- marker length in pixels\n    local marker_step = 10  -- step in reticle units (MILs/MOAs)\n    \n    for i = marker_step, 50, marker_step do\n        -- Line up\n        fb:c_vline(_x(0), _y(i), marker_length, BLACK) \n        -- Line down\n        fb:c_vline(_x(0), _y(-i), marker_length, BLACK) \n        \n        -- Numerical markers (using 6x6 font)\n        fb:c_text6(tostring(i), _x(5), _y(i), BLACK)\n    end\n\n    -- Dynamic detail adaptation\n    -- If zoom is high (ax \u003c 0.5), draw additional markers every 5 units\n    if ax \u003c 0.5 then\n        for i = 5, 50, 5 do\n            -- Small pixel dot at 5 units to the right\n            fb:c_pixel(_x(i), _y(-5), BLACK) \n        end\n    end\n    \n    return fb \nend\n```\n\n### 🎨 ReticleDraw Methods (Centered Coordinates)\n\nThese methods automatically draw relative to the display center (`0,0`). **Always use `_x()` and `_y()`** for all coordinates measured in reticle units.\n\n| Method | Description | Example |\n| :--- | :--- | :--- |\n| **`fb:c_pixel(x, y, color)`** | Draws a single pixel. | `fb:c_pixel(_x(10), _y(10), BLACK)` |\n| **`fb:c_line(x0, y0, x1, y1, color)`** | Draws a line. | `fb:c_line(0, 0, _x(50), 0, BLACK)` |\n| **`fb:c_hline(x, y, width, color)`** | Draws a horizontal line. | `fb:c_hline(_x(-50), _y(20), _x(100), BLACK)` |\n| **`fb:c_vline(x, y, height, color)`** | Draws a vertical line. | `fb:c_vline(_x(30), _y(-50), _y(100), BLACK)` |\n| **`fb:c_rect(x, y, w, h, color)`** | Draws a rectangle outline (center `x, y`). | `fb:c_rect(_x(10), _y(10), 20, 20, BLACK)` |\n| **`fb:c_fill_rect(x, y, w, h, color)`**| Draws a filled rectangle. | `fb:c_fill_rect(0, 0, 3, 3, BLACK)` |\n| **`fb:c_circle(x, y, r, color)`** | Draws a circle outline. `r` is the radius in **pixels**. | `fb:c_circle(0, _y(30), 5, BLACK)` |\n| **`fb:c_fill_circle(x, y, r, color)`** | Draws a filled circle. | `fb:c_fill_circle(0, 0, 2, BLACK)` |\n| **`fb:c_text6(s, x, y, color)`** | Draws text using the **6x6** pixel font. | `fb:c_text6(\"10\", _x(10), _y(-10), BLACK)` |\n| **`fb:c_arc(x, y, rx, ry, start_angle, end_angle, color)`** | Draws an arc from `start_angle` to `end_angle` (degrees, 0° = 12 o'clock). | `fb:c_arc(0, 0, 20, 20, 0, 90, BLACK)` |\n\n\n### 📐 Inherited FrameBuffer Methods (Absolute Coordinates)\n\nThese methods require **absolute pixel coordinates** (`0,0` is the top-left corner).\n\n| Method | Coordinate Requirement | Description |\n| :--- | :--- | :--- |\n| **`fb:pixel(x, y, color)`** | Absolute | Sets the color of a pixel. |\n| **`fb:fill(color)`** | Absolute | Fills the entire buffer. |\n| **`fb:fill_rect(x, y, w, h, c)`** | Absolute | Fills a rectangle. |\n| **`fb:rect(x, y, w, h, c)`** | Absolute | Draws a rectangle outline. |\n| **`fb:line(x0, y0, x1, y1, color)`**| Absolute | Draws an arbitrary line. |\n| **`fb:hline(x, y, w, color)`** | Absolute | Draws a horizontal line. |\n| **`fb:vline(x, y, h, color)`** | Absolute | Draws a vertical line. |\n| **`fb:circle(x, y, r, color)`** | Absolute | Draws a circle outline. |\n| **`fb:fill_circle(x, y, r, color)`** | Absolute | Draws a filled circle. |\n| **`fb:ellipse(x, y, rx, ry, color)`** | Absolute | Draws an ellipse outline. |\n| **`fb:polygon(points, color)`** | Absolute | Draws a filled polygon. |\n| **`fb:text(s, x0, y0, col)`** | Absolute | Draws text using the standard **8x8** pixel font. |\n| **`fb:arc(cx, cy, rx, ry, start_angle, end_angle, color)`** | Absolute | Draws an arc. Angles in degrees, 0° = 12 o'clock. |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-murphy%2Fbcrg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo-murphy%2Fbcrg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-murphy%2Fbcrg/lists"}