{"id":27057820,"url":"https://github.com/mrange/funbasic","last_synced_at":"2025-07-13T12:38:47.490Z","repository":{"id":149116938,"uuid":"46948943","full_name":"mrange/funbasic","owner":"mrange","description":null,"archived":false,"fork":false,"pushed_at":"2015-12-02T21:56:10.000Z","size":1049,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T02:09:04.998Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrange.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-26T22:17:47.000Z","updated_at":"2015-11-26T22:20:47.000Z","dependencies_parsed_at":"2023-04-14T20:56:35.961Z","dependency_job_id":null,"html_url":"https://github.com/mrange/funbasic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrange%2Ffunbasic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrange%2Ffunbasic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrange%2Ffunbasic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrange%2Ffunbasic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrange","download_url":"https://codeload.github.com/mrange/funbasic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332057,"owners_count":20921849,"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","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":[],"created_at":"2025-04-05T11:33:25.724Z","updated_at":"2025-04-05T11:33:29.754Z","avatar_url":"https://github.com/mrange.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# funbasic\n\nThe real repository for funbasic is [here](https://bitbucket.org/ptrelford/funbasic)\n\nThis place is just for my experiments and tweaks of funbasic\n\n![FunBasic! now with extra lame graphics](https://raw.githubusercontent.com/mrange/funbasic/master/images/fb.PNG)\n\nAimed at @ptrelford\n===================\n\nSo it's still in a bit rough shape, I cheated quite much just to get it run\non desktop. FunBasic.Runner.sln is the desktop solution I am fooling around in.\n`fbi` is an embryo for a console application that runs FunBasic sources.\n\nAnyway, I fooled around with Direct2D and SmallBasic before because I thought the\nvisuals in SmallBasic was way too slow. This is basically a port of that work\nrewritten in F#. Direct2D are in many ways great as it has many high-level\ngraphic primitives (like brushes) while giving good performance.\n\nIf we are talking raw-performance Direct3D crushes Direct2D but then we are\nbasically pushing triangles and doing tesselation ourselves.\n\nI am using Direct3D11 but it's quite possible to backport to Direct3D9.\n\nAPI Ideas\n=========\n\nI think it's important that the API (and FunBasic is general) are forgiving.\n\nNo random crashes because of slightly wrong indata. Better to render what we got\nas good as we can (using fallback brushes if necessary).\n\nThe API lets the developer create objects such as rectangles, ellipses,\n bitmaps and so on. These persists on screen until removed. I think this model\nis easier to understand than redrawing each frame from scratch (which for real-life\napplications are often better).\n\nSo the example program (lo-fi graphics here)\n\n```\nD2D.ShowWindow ()\n\nD2D.ClearVisuals ()\n\n' Numbers used to assign different D2D objects\n'   TextFormats, Bitmaps, Brushes and Visuals all have their own\n'   number series\ntextFormat_std  = 0001\n\nbitmap_ufo      = 0001\n\nbrush_fill      = 0001\nbrush_stroke    = 0002\nbrush_radialfill= 0003\nbrush_radialfill= 0004\n\nvisual_rect     = 0001\nvisual_ellipse  = 0002\nvisual_text     = 0003\nvisual_ufos     = 1000\n\nnumber_of_ufos  = 3\n\n' Sets the background to a darkblue (#rgb)\nD2D.SetBackground               (\"#003\")\n\n' Download a nice ufo\n'   Note that this starts the download process but doesn't block\n'   This enables you to download multiple bitmaps simultanenously\nD2D.DownloadBitmap              (bitmap_ufo       , \"http://blitzetc.ru/images/5/5a/BMax-UFO.png\")\n\n' Create a text format that will be used to render text\n'   If no text format can be found a default will be used\nD2D.CreateTextFormat            (textFormat_std   , \"Tahoma\", 48)\n\n' Create some solid brushes\nD2D.CreateSolidBrush            (brush_fill       , \"#0FF\")\nD2D.CreateSolidBrush            (brush_stroke     , \"#00FF7f\")\n\n' Create a radial brush to make some nice looking spheres\n'                                                   CenterX CenterY RadiusX RadiusY OffsetX OffsetY ExtendMode\nD2D.CreateRadialGradientBrush   (brush_radialfill , 0.5   , 0.5   , 1,      1,      -0.25 , -0.25,  \"clamp\")\n' Create a gradient stop                            Color   Offset\nD2D.CreateGradientStopForBrush  (brush_radialfill , \"#fff\", 0)\nD2D.CreateGradientStopForBrush  (brush_radialfill , \"#07f\", 0.15)\nD2D.CreateGradientStopForBrush  (brush_radialfill , \"#004\", 1)\n\n' Create a linear brush to make some nice looking bars\n'                                                   StartX  StartY  EndX  EndY ExtendMode\nD2D.CreateLinearGradientBrush   (brush_linearfill , 0     , 0     , 0   , 1,  \"clamp\")\n' Create a gradient stop                            Color   Offset\nD2D.CreateGradientStopForBrush  (brush_linearfill , \"#024\", 0)\nD2D.CreateGradientStopForBrush  (brush_linearfill , \"#05A\", 0.25)\nD2D.CreateGradientStopForBrush  (brush_linearfill , \"#08F\", 0.5)\nD2D.CreateGradientStopForBrush  (brush_linearfill , \"#05A\", 0.75)\nD2D.CreateGradientStopForBrush  (brush_linearfill , \"#024\", 1)\n\n' Wait for all downloads to complete\nD2D.WaitForDownloadsToComplete  ()\n\n' Create a text visual\nD2D.CreateTextVisual            (visual_text    , textFormat_std , 1, 400, 400, 800, 60, \"Direct2D + FunBasic\")\n' Create a rectangle visual using the linear gradient brush\nD2D.CreateRectangleVisual       (visual_rect    , brush_linearfill, 0, 0, 400, 0, 800, 60)\n' Create a ellipse visual using the radial gradient brush\nD2D.CreateEllipseVisual         (visual_ellipse , brush_radialfill, brush_stroke, 3, 200, 200, 125, 125)\n' Create a bitmap visual of the downloaded UFO\nD2D.CreateBitmapVisual          (visual_ufos + 0, bitmap_ufo, 1, 200, 300, 160, 128)\n' Clone the ufo visual a few times\nFor i = 1 To number_of_ufos\n  D2D.CloneVisual (visual_ufos + i, visual_ufos + 0)\nEndFor\n\n' Make sure the ellipse visual is rendered on below all other visuals\n'   Usually the order of visual is decided by the creation order\nD2D.MoveVisualToBottom          (visual_ellipse)\n\n' Make sure the text \u0026 rect visual are rendered below all other visuals\nD2D.MoveVisualToTop             (visual_rect)\nD2D.MoveVisualToTop             (visual_text)\n\ni = 0\nx = 0\ny = 0\n\nWhile D2D.LastKey = \"\"\n  i = i + 1\n  x = i * 2\n  y = i * 1\n  r = i * 0.03\n\n\n  rx = 550.0 + 100.0*Math.Sin (3*ri)\n  ry = 200.0 + 100.0*Math.Cos (ri)\n  ' Move the rectangle \u0026 text\n  D2D.MoveVisual (visual_rect, 400, ry)\n  D2D.MoveVisual (visual_text, rx, ry)\n\n  ' Move the ufos\n  For ii = 0 To number_of_ufos\n    ri = r + ii\n    ux = 200.0 + 100.0*Math.Sin (ri)\n    uy = 200.0 + 100.0*Math.Cos (ri)\n    D2D.MoveVisual (visual_ufos + ii, ux, uy)\n  EndFor\n\n  ' Wait for screen refresh\n  D2D.WaitForRefresh ()\nEndWhile\n\nD2D.CloseWindow ()\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrange%2Ffunbasic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrange%2Ffunbasic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrange%2Ffunbasic/lists"}