1import{D as e,E as t,H as n,O as r,P as i,V as a,W as o,_ as s,d as c,f as l,g as ee,h as u,j as d,k as te,l as f,m as p,n as ne,p as m,r as re,u as h,z as ie}from"./app-DCiJdU1q.js";import{n as g,r as _,t as v}from"./vue.CxU8BAii-f1GBI8FO.js";var y=o({default:()=>b}),b=`/assets/2020-08-15-D8eHYoOA.mp4`,x=o({default:()=>S}),S=`/assets/2020-12-16-CsaofJBs.mp4`,C=o({default:()=>w}),w=`/assets/2020-12-18-Bt5nmB2O.mp4`,T=o({default:()=>E}),E=`/assets/2021-04-14-BpYRHJ9x.mp4`,D=o({default:()=>O}),O=`/assets/2022-01-08-DKvOs2Bi.mp4`,k=o({default:()=>A}),A=`/assets/2022-08-11-DHjx0Nuh.mp4`,j=o({default:()=>M}),M=`/assets/2023-04-19-1isn_Ohc.mp4`,N=o({default:()=>P}),P=`/assets/2023-07-28-BSkvZD32.mp4`,F=o({default:()=>I}),I=`/assets/2023-09-01-DpzaSvre.mp4`,L=o({default:()=>R}),R=`/assets/2023-09-13-DTFgr3Br.mp4`,z=o({default:()=>B}),B=`/assets/2024-01-31-CCTrhckI.mp4`,V=o({default:()=>H}),H=`/assets/2024-04-22-BJu2aI7E.mp4`,U=o({default:()=>W}),W=`/assets/2024-06-11-JeQ2LS81.mp4`,G=o({default:()=>K}),K=`/assets/2024-09-01-B_k72weJ.mp4`,q=o({default:()=>J}),J=`/assets/2024-10-09-DuS_uK2K.mp4`,Y=o({default:()=>ae}),ae=`/assets/2024-11-11-DR3ngXKh.mp4`,oe=o({default:()=>se}),se=`/assets/2024-11-12-BH1myBy4.mp4`,ce=o({default:()=>le}),le=`/assets/2025-03-04-C569E6mI.mp4`,ue=o({default:()=>de}),de=`/assets/2025-06-05-Uc7trrtZ.mp4`,fe=o({default:()=>pe}),pe=`/assets/2025-06-11-B24ac1av.mp4`,me=o({default:()=>he}
1),he=`/assets/2025-07-03-D6oUp-7i.mp4`,ge=o({default:()=>_e}),_e=`/assets/2025-08-12-BT7hbsyZ.mp4`,ve=o({default:()=>ye}),ye=`/assets/2026-04-17-CQFfPXGO.mp4`,be=o({default:()=>xe}),xe=`/assets/2024-02-22-CwOwucyH.gif`,Se=o({default:()=>Ce}),Ce=`/assets/2025-03-14-CpxvqGPg.jpeg`,we=o({default:()=>Te}),Te=`/assets/2025-06-07-M_MjNEg1.jpeg`,Ee=o({default:()=>De}),De=`/assets/2025-07-04-B3-wEdNo.jpeg`,Oe=o({default:()=>ke}),ke=`/assets/2025-07-07-CP0aZrW4.gif`,Ae=o({default:()=>je}),je=`/assets/2025-08-13-CEqwBqKR.png`,Me=[`href`],Ne={key:0},Pe=[`src`],Fe=[`src`],Ie={class:`prose prose-sm p4 m0 pb3`},Le={op50:``,"text-sm":``,pt2:``},X=s({__name:`WrapperLab`,props:{frontmatter:{type:Object,required:!0},media:{type:Object},date:{type:String,required:!0}},setup(r){let i=r;function a(){let e=`https://embed.bsky.app/static/embed.js`;if(!document.querySelector(`script[src="${e}"]`)){let t=document.createElement(`script`);t.src=e,t.async=!0,t.charset=`utf-8`,document.head.appendChild(t)}}return t(()=>{i.media?.type===`embed`&&i.media.content.includes(`bluesky-embed`)&&a()}),(t,i)=>(e(),p(`div`,null,[c(`a`,{border:`~ base rounded-lg`,block:``,"of-hidden":``,class:`group`,hover:`scale-101 shadow-xl z-10 select-text`,"transition-treansform":``,"duration-300":``,"bg-base":``,relative:``,"transform-gpu":``,href:r.frontmatter.link,target:`_blank`},[r.media?(e(),p(`div`,Ne,[r.media.type===`video`?(e(),p(`video`,{key:0,src:r.media.content,preload:`none`,"w-full":``,autoplay:``,loop:``,muted:``,playsinline:``},null,8,Pe)):r.media.type===`image`?(e(),p(`img`,{key:1,loading:`lazy`,src:r.media.content,"w-full":``,alt:`Demonstration media`},null,8,Fe)):m(``,!0)])):m(``,!0),c(`div`,Ie,[te(t.$slots,`default`),c(`div`,Le,n(ie(_)(r.date,!1)),1)])],8,Me)]))}}),Re=o({default:()=>ze}),ze={__name:`2020-08-15`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð ï¸ Unity: Inverse Kinematics Study`)]),c(`p`,null,`Exploring runtime IK solutions in Unity using the Prototype Asset Pack for character rigs. Implemented goal-driven limb positioning with realâtime adjustments.`),c(`p`,null,[c(`strong`,null,`Assets:`),u(` POLYGON | Prototype Asset Pack by Unity Technologies`)])],-1)]]),_:1})}}},Be=o({default:()=>Ve}),Ve={__name:`2020-12-16`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð ï¸ Unity: Dynamic Camera FoV Adapter`)]),c(`p`,null,`A code that adjusts the Cameraâs field of view at runtime to encompass a set of tracked Transforms within defined margins.`)],-1)]]),_:1})}}},He=o({default:()=>Ue}),Ue={__name:`2020-12-18`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,`𧪠Remap Function Test: Value to Range Mapping`),c(`p`,null,`Ran a simple visual test to validate a remap function, converting a value from one range to another in real time.`)],-1)]]),_:1})}}},We=o({default:()=>Ge}),Ge={__name:`2021-04-14`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ðª Unity: Raymarched Sphere on a Billboard Quad`)]),c(`p`,null,`Used simple raymarching on a billboard quad to simulate a 3D sphere. Replaced high-poly planet meshes with a single shader pass. Perfect for educational solar system sims on low-end devices. Clean, fast, and visually solid.`)],-1)]]),_:1})}}},Ke=o({default:()=>qe}),qe={__name:`2022-01-08`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¹ Unity: Donut County Prototype`)]),c(`p`,null,`A physicsâdriven holeâdigging game prototype inspired by Donut C
1ounty, built entirely in Unity to test core mechanics and feel.`)],-1)]]),_:1})}}},Je=o({default:()=>Ye}),Ye={__name:`2022-08-11`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¬ Virtual Production: UE5 Pipeline Fix`)]),c(`p`,null,`Recorded a virtual production scene in Unreal Engine 5 to debug pipeline issues. Found and fixed a desync between the matte layer and foreground render.`)],-1)]]),_:1})}}},Xe=o({default:()=>Ze}),Ze={__name:`2023-04-19`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_unity-gamedev-jobsystem-activity-7348828913223065603-RUua`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_unity-gamedev-jobsystem-activity-7348828913223065603-RUua`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð ï¸ Unity: Multithreaded + Time Slicing + Delayed Result Gathering`)]),c(`p`,null,[u(`Experimenting with Unityâs Job System and Burst compiler to speed up line casts on a grid and update an exposure map in Unity. By leveraging `),c(`em`,null,`IJobParallelFor`),u(`, delayed result gathering, and frame slicing, Iâve hit some impressive numbers:`)]),c(`p`,null,[c(`strong`,null,`Whatâs implemented:`)]),c(`ul`,null,[c(`li`,null,[c(`strong`,null,`IJobParallelFor`),u(` jobs for parallel line casts`)]),c(`li`,null,`Delayed result gathering on the main thread to avoid stalls`),c(`li`,null,`Time slicing to spread work over multiple frames`)]),c(`p`,null,[c(`strong`,null,`Inspiration:`),u(` Based on `),c(`a`,{href:`https://allenchou.net/2021/05/time-slicing`,target:`_blank`,rel:`noopener`},`MingâLun âAllenâ Chouâs`),u(` approach in Unityâs Job System.`)])],-1)]]),_:1})}}},Qe=o({default:()=>$e}),$e={__name:`2023-07-28`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð OpenGL: Skybox Implementation`)]),c(`p`,null,`Added a skybox system using cube maps in OpenGL. View-locked, depth-tested, and rendered last for proper blending. Clean backdrop, zero artifacts, and ready for HDR probes.`)],-1)]]),_:1})}}},et=o({default:()=>tt}),tt={__name:`2023-09-01`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_2d
1physics-collisiondetection-datastructure-activity-7103372002752655360-it7T`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_2dphysics-collisiondetection-datastructure-activity-7103372002752655360-it7T`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð ï¸ Quadtree Spatial Partitioning`)]),c(`p`,null,`Optimized 2D collision detection and spatial queries using a quadtree in SDL2. Visual debug and performance logging reveal major gains over brute force.`),c(`p`,null,[c(`strong`,null,`Key features:`)]),c(`ul`,null,[c(`li`,null,`Quadtree nodes with dynamic subdivision`),c(`li`,null,`Efficient range queries for nearby objects`),c(`li`,null,`SDL2 overlay of quadtree bounds and entities`)]),c(`p`,null,[u(`Based on `),c(`a`,{href:`https://thecodingtrain.com/challenges/98-quadtree`,target:`_blank`,rel:`noopener`},`The Coding Trainâs Quadtree challenge`)])],-1)]]),_:1})}}},nt=o({default:()=>rt}),rt={__name:`2023-09-13`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¦ Frustum Culling + AABB`)]),c(`p`,null,`Implemented frustum culling using axis-aligned bounding boxes. Each objectâs AABB is tested against the view frustum planes before rendering. Simple, fast, and cut draw calls by over 70% in large scenes.`)],-1)]]),_:1})}}},it=o({default:()=>at}),at={__name:`2024-01-31`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_indiegamedev-programming-physicsengine-activity-7158451446781296640--KHA`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_indiegamedev-programming-physicsengine-activity-7158451446781296640--KHA`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð Dura2D: Building a 2D Physics Engine for Learning`)]),c(`p`,null,`I set out to discover how games simulate rigid bodies and collisions by coding my own 2D physics engine from scratch. Dura2D grew from a question: how do games deliver realistic motion and interactions?`),c(`p`,null,[u(`Inspired by `),c(`a`,{href:`https://pikuma.com/courses/game-physics-engine-programming`,target:`_blank`,rel:`noopener`},`Pikumaâs course`),u(`, `),c(`a`,{href:`https://allenchou.net/category/physics`,target:`_blank`,rel:`noopener`},`Ming-Lun "Allen" Chou Game Physics blog posts`),u(` and `),c(`a`,{href:`https://github.com/erincatto/box2d`,target:`_blank`,rel:`noopener`},`Erin Cattoâs Box2D code`),u(`, Dura2D offers:`)]),c(`ul`,null,[c(`li`,null,`Constraint System for joints and contacts`),c(`li`,null,`Warm Starting to reuse previous frame impulses and boost stability`),c(`li`,null,`Stable, realâtime simulation across different scenarios`)])],-1)]]),_:1})}}},ot=o({default:()=>st}),st={__name:`2024-02-22`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_chip8-intrepreter-cpp-activity-7166373441867038720-7cqL`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_chip8-intrepreter-cpp-activity-7166373441867038720-7cqL`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,[u(`ð§© Chip0u: A CHIP-8 Emulator in `),c(`code`,null,`C++20`),u(` with `),c(`code`,null,`raylib`),u(` + `),c(`code`,null,`ImGui`)])]),c(`p`,null,`A playful and modern take on the classic CHIP-8 virtual machine, written in C++20 with a focus on clarity and UX.`),c(`p`,null,`Whatâs implemented:`),c(`ul`,null,[c(`li`,null,`Full CHIP-8 instruction set with accurate timing and quirk handling`),c(`li`,null,`Built-in debugger with step, breakpoint, and memory inspection`),c(`li`,null,[u(`UI built with `),c(`code`,null,`ImGui`),u(`, rendered using `),c(`code`,null,`raylib`)]),c(`li`,null,`Key remapping and save state support`),c(`li`,null,`Loads and runs most public domain ROMs with zero config`)]),c(`p`,null,`Designed to feel light and responsive while offering deep control for learning and experimentation.`)],-1)]]),_:1})}}},ct=o({default:()=>lt}),lt={__name:`2024-04-22`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_unrealengine-frunnable-multithreading-activity-7105914700369932288-vimd`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_unrealengine-frunnable-multithreading-activity-7105914700369932288-vimd`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð ï¸ Unreal Engine 5: Multithreaded + Time Slicing + Delayed Result Gathering`)]
1),c(`p`,null,`Experimenting with FRunnable to speed up line casts on a grid and update an exposure map in UE5. By combining FRunnable, delayed result gathering, and time slicing, I hit some impressive numbers:`),c(`p`,null,[c(`strong`,null,`Whatâs implemented:`)]),c(`ul`,null,[c(`li`,null,[c(`strong`,null,`FRunnable`),u(` tasks for parallel line casts`)]),c(`li`,null,`Delayed result gathering to avoid mainâthread stalls`),c(`li`,null,`Time slicing to split work across frames`)]),c(`p`,null,[c(`strong`,null,`Inspiration:`),u(` Adapted the Unity Job System approach from `),c(`a`,{href:`https://allenchou.net/2021/05/time-slicing`,target:`_blank`,rel:`noopener`},`MingâLun âAllenâ Chouâs blog`),u(` to Unreal Engine.`)])],-1)]]),_:1})}}},ut=o({default:()=>dt}),dt={__name:`2024-06-11`,setup(t){let n={meta:[]};return v({meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,`ð ï¸ 2D SDF Interactive Demo`),c(`p`,null,`Realâtime 2D Signed Distance Field demo generating smooth shapes and animations purely from simple equations.`)],-1)]]),_:1})}}},ft=o({default:()=>pt}),pt={__name:`2024-09-01`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_gamedev-gameprogramming-indiedev-activity-7258081478280957952-YpoJ`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_gamedev-gameprogramming-indiedev-activity-7258081478280957952-YpoJ`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð³ Dynamic AABB Tree`)]),c(`p`,null,`Iâve integrated a full dynamic AABB tree system into Dura2D, inspired by Box2D, and the performance boost was immediate.`),c(`p`,null,[c(`strong`,null,`Whatâs implemented:`)]),c(`ul`,null,[c(`li`,null,[c(`p`,null,[c(`strong`,null,`Surface Area Heuristic (SAH)`),u(` Balances the tree by minimizing the total surface cost. Instead of using height or node count, SAH makes smarter split and rotation decisions, reducing overlap and traversal steps.`)])]),c(`li`,null,[c(`p`,null,[c(`strong`,null,`Fat AABB`),u(` Each object has a slightly larger bounding box to allow small movements without triggering tree updates. This reduces the number of insertions and keeps the tree stable.`)])]),c(`li`,null,[c(`p`,null,[c(`strong`,null,`Memory Management`),u(` Nodes are managed through a fixed-size pool with a free list. No dynamic memory allocation during runtime, which improves stability and frame consistency.`)])])]),c(`p`,null,[c(`strong`,null,`Result:`),u(` The broad-phase is now fast, efficient, and scales well under load. Dura2D handles large scenes more easily, and the tree stays compact and responsive even with constant movement.`)])],-1)]]),_:1})}}},mt=o({default:()=>ht}),ht={__name:`2024-10-09`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_psp-c-pspsdk-activity-7249742548074717185-C9W4`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_psp-c-pspsdk-activity-7249742548074717185-C9W4`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`⨠Basic Sony PSP rendering`)]),c(`p`,null,[u(`Revisiting my childhood passion by programming graphics on the original PlayStation Portable. Using `),c(`code`,null,`pspdev/pspsdk`),u(` and `),c(`code`,null,`pspgl`),u(` (an OpenGL ESâlike layer) to get native rendering up and running.`)])],-1)]]),_:1})}}},gt=o({default:()=>_t}),_t={__name:`2024-11-11`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_shaders-webgl-glsl-activity-7261768401742651392-jy6d`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_shaders-webgl-glsl-activity-7261768401742651392-jy6d`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¨ Shader.Vista: MultiâPass Shader Web Editor`)]),c(`p`,null,`A browserâbased tool for creating and experimenting with multiâpass fragment shaders.`),c(`p`,null,[c(`strong`,null,`Whatâs in place:`)]),c(`ul`,null,[c(`li`,null,`Monaco Editor integration for code editing`),c(`li`,null,`WebGL 1 and WebGL 2 contexts with shader compilation`),c(`li`,null,`Multiâpass rendering pipeline with framebuffer swapping`),c(`li`,null,`UI layout styled with Tailwind CSS`),c(`li`,null,`Dragâandâdrop ordering of render passes via DnD Kit`)])],-1)]]),_:1})}}},vt=o({default:()=>yt}),yt={__name:`2024-11-12`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_codeoptimization-lowlevelcoding-optimizationhacks-activity-7262070540868218880--v6k`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_codeoptimization-lowlevelcoding-optimizationhacks-activity-7262070540868218880--v6k`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`â¡ Pathfinding Performance: A Testbed Optimizations`)]),c(`p`,null,`I built a custom pathfinding testbed and explored 16,310 nodes in about 0.33 ms. Each colored pixel shows lowâlevel tweaks at work:`),c(`p`,null,[c(`strong`,null,`Key experiments that unlocked speed:`)]),c(`p`,null,[c(`strong`,null,`Memory layout`)]),c(`ul`,null,[c(`li`,null,`Pack structs to remove padding`),c(`li`,null,`Align hot functions to cut cache misses`),c(`li`,null,`Pack frequent data tightly`),c(`li`,null,`Add manual prefetching in A* loops`)]),c(`p`,null,[c(`strong`,null,`C
1ompute optimizations`)]),c(`ul`,null,[c(`li`,null,`Inline distance math and use SSE2`),c(`li`,null,`Ensure proper loop order for better cache locality`)]),c(`p`,null,[c(`strong`,null,`Task control`)]),c(`ul`,null,[c(`li`,null,`Simple fiberâbased job system`),c(`li`,null,`Time slicing to balance work`),c(`li`,null,`Delay result gathering`)]),c(`p`,null,[u(`Big thanks to `),c(`a`,{href:`https://github.com/dendibakh/perf-ninja2024-11-11`,target:`_blank`,rel:`noopener`},`Perf Ninja`),u(` for the lowâlevel inspiration. Still room to push this further.`)])],-1)]]),_:1})}}},bt=o({default:()=>xt}),xt={__name:`2025-03-04`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_opensource-raylib-softwaredevelopment-activity-7313211647190302720-TF-u`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_opensource-raylib-softwaredevelopment-activity-7313211647190302720-TF-u`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¹ï¸ Dura2D Running on a Nintendo Switch`)]),c(`p`,null,[u(`Got `),c(`code`,null,`Dura2D`),u(`, my custom 2D physics engine, running natively on a modded Nintendo Switch using the `),c(`a`,{href:`https://devkitpro.org`,target:`_blank`,rel:`noopener`},`devkitPro`),u(` homebrew toolchain.`)]),c(`p`,null,`Whatâs been achieved:`),c(`ul`,null,[c(`li`,null,`Ported core physics loop.`),c(`li`,null,`Ran physics demos in real time on handheld mode.`),c(`li`,null,`Kept it fast, small, and fully self-contained.`)]),c(`p`,null,`The project is an exercise in pushing homebrew boundaries while keeping the architecture minimal and portable.`)],-1)]]),_:1})}}},St=o({default:()=>Ct}),Ct={__name:`2025-03-14`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_gameboy-audioprogramming-retro-activity-7306406455371292672-ZBQO`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_gameboy-audioprogramming-retro-activity-7306406455371292672-ZBQO`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð GameBoy Audio Visualizer`)]),c(`p`,null,`A simple, real-time visualizer for the Game Boyâs four audio channels, designed to help me understand and debug the APU while I add sound to my emulator.`)],-1)]]),_:1})}}},wt=o({default:()=>Tt}),Tt={__name:`2025-06-05`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_emulators-programming-challenge-activity-7336494435913863171-hEXm`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_emulators-programming-challenge-activity-7336494435913863171-hEXm`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,[u(`ð§© MOS 6502 Emulator Written in `),c(`code`,null,`C99`)])]),c(`p`,null,`A clean and minimal MOS 6502 emulator built entirely in C99, focused on correctness, readability, and low-level understanding.`),c(`p`,null,`Whatâs working so far:`),c(`ul`,null,[c(`li`,null,`Full instruction set implemented and verified`),c(`li`,null,`Accurate cycle timing and flag behavior`),c(`li`,null,`Memory-mapped bus with support for RAM, ROM, and I/O regions`),c(`li`,null,`Designed to be embedded into other systems or used for standalone programs`)]),c(`p`,null,`A foundational project to better understand how 8-bit CPUs work and how to build emulators from the ground up.`)],-1)]]),_:1})}}},Et=o({default:()=>Dt}),Dt={__name:`2025-06-07`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_ray-tracing-normal-aesthetics-activity-7336910518760148992-YOpK`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_ray-tracing-normal-aesthetics-activity-7336910518760148992-YOpK`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`⨠Ray Tracing & the Aesthetics of Normals`)]),c(`p`,null,[u(`Exploring how surface `),c(`strong`,null,`normals`),u(` shape the visual soul of ray-traced scenes.`)])],-1)]]),_:1})}}},Ot=o({default:()=>kt}),kt={__name:`2025-06-11`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_raymarching-fragmentshader-shaderart-activity-7338571018875105282-BVFJ`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_raymarching-fragmentshader-shaderart-activity-7338571018875105282-BVFJ`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð«ï¸ Explaining Ray Marching⦠with Ray Marching`)]),c(`p`,null,[u(`A meta-visual experiment: using real-time `),c(`code`,null,`ray marching`),u(` to `),c(`strong`,null,`explain how ray marching works`),u(`, directly in the browser.`)]),c(`p`,null,`Features:`),c(`ul`,null,[c(`li`,null,`A minimal SDF-based ray marcher using signed distance fields`),c(`li`,null,`Interactive visualizations: orbit camera, distance debug view, and step tracing overlay`),c(`li`,null,[u(`Embedded directly into the blog post. The explanation `),c(`em`,null,`is`),u(` the render`)])]),c(`p`,null,`ð¯ Goal: make an intuitive, visual-first introduction to ray marching that teaches by showing, not telling.`)],-1)]]),_:1})}}},At=o({default:()=>jt}),jt={__name:`2025-07-03`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_gamedev-retrogaming-psp-activity-7346550444678090752-MQqO`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_gamedev-retrogaming-psp-activity-7346550444678090752-MQqO`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¹ï¸ Dura2D + LeveGL on PSP`)]),c(`p`,null,[u(`Running my own 2D physics engine (`),c(`code`,null,`Dura2D`),u(`) and minimalist OpenGL-style wrapper (`),c(`code`,null,`LeveGL`),u(`) on real `),c(`code`,null,`Sony PSP`),u(` hardware.`)]),c(`p`,null,`What Iâve pulled off so far:`),c(`ul`,null,[c(`li`,null,[c(`strong`,null,`Libraries ported to pspsdk`),u(`, with all system dependencies replaced.`)]),c(`li`,null,[c(`strong`,null,`Rendering pipeline and physics adapted`),u(` for PSPâs `),c(`strong`,null,`fixed-function GPU`),u(` and `),c(`strong`,null,`tight memory budget`),u(`.`)]),c(`li`,null,[u(`Demos successfully run at `),c(`strong`,null,`full resolution on a PSP 3000`),u(`.`)])]),c(`p`,null,`ð¸ Captured the result in a short recording real-time simulation and rendering, powered entirely by homebrew code.`)],-1)]]),_:1})}}},Mt=o({default:()=>Nt}),Nt={__name:`2025-07-04`,setup(t){let n={link:`https://github.com/zschzen/RayTracing-One-Week`,meta:[]};return v({link:`https://github.com/zschzen/RayTracing-One-Week`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`⨠Ray Tracing in One Weekend`)]),c(`p`,null,[u(`A handsâon journey building a CPU-based ray tracer from scratch, fully in `),c(`code`,null,`C99`),u(`, following `),c(`a`,{href:`https://raytracing.github.io/books/RayTracingInOneWeekend.html`,target:`_blank`,rel:`noopener`},[c(`em`,null,`Ray Tracing in One Weekend`)]),u(` by Peter Shirley.`)]
1)],-1)]]),_:1})}}},Pt=o({default:()=>Ft}),Ft={__name:`2025-07-07`,setup(t){let n={link:`https://github.com/SOHNE/CameBoy`,meta:[]};return v({link:`https://github.com/SOHNE/CameBoy`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,[u(`ð§© CameBoy: A Minimalist Game Boy Emulator in `),c(`code`,null,`C99`)])]),c(`p`,null,`A clean, from-scratch Game Boy emulator written in pure C99, with a focus on simplicity, clarity, and low-level accuracy.`),c(`p`,null,[c(`strong`,null,`ð Resources that shaped this project`)]),c(`ul`,null,[c(`li`,null,[c(`a`,{href:`https://gbdev.io/pandocs`,target:`_blank`,rel:`noopener`},`Pan Docs`),u(`, the most complete technical reference`)]),c(`li`,null,[c(`a`,{href:`https://www.copetti.org/writings/consoles/game-boy`,target:`_blank`,rel:`noopener`},`Rodrigo Copettiâs Console Architecture Guide`)]),c(`li`,null,[c(`a`,{href:`https://github.com/Gekkio/gb-ctr`,target:`_blank`,rel:`noopener`},`Gekkioâs Hardware Research`)]),c(`li`,null,[c(`a`,{href:`https://media.ccc.de/v/33c3-8029-the_ultimate_game_boy_talk`,target:`_blank`,rel:`noopener`},`The Ultimate Game Boy Talk (33C3)`)]),c(`li`,null,[c(`a`,{href:`https://www.youtube.com/watch?v=e87qKixKFME&list=PLVxiWMqQvhg_yk4qy2cSC3457wZJga_e5`,target:`_blank`,rel:`noopener`},`Game Boy Emulator Dev Series on YouTube`)])])],-1)]]),_:1})}}},Z=o({default:()=>It}),It={__name:`2025-08-12`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_gameoflife-cellularautomata-programming-activity-7361362088000131072-z3Z5`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_gameoflife-cellularautomata-programming-activity-7361362088000131072-z3Z5`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð§© Conwayâs Game of Life: Sparse Encoding`)]),c(`p`,null,[c(`strong`,null,`Inspiration:`)]),c(`p`,null,[c(`a`,{href:`https://youtu.be/OqfHIujOvnE`,target:`_blank`,rel:`noopener`},[u(`Huge 2`),c(`sup`,null,`64`),u(` Conwayâs Game Of Life Sim, using Sparse Encoding`)])])],-1)]]),_:1})}}},Lt=o({default:()=>Rt}),Rt={__name:`2025-08-13`,setup(t){let n={link:`https://github.com/zschzen/GLASM`,meta:[]};return v({link:`https://github.com/zschzen/GLASM`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`ð¨ OpenGL-ASM x64 NASM Project (GLASM)`)]),c(`p`,null,[u(`Simple OpenGL 1.1 demo rendering a triangle using `),c(`strong`,null,`GLFW`),u(` and `),c(`strong`,null,`NASM assembly`),u(` on x64 platforms.`)]),c(`p`,null,[c(`strong`,null,`Features:`)]),c(`ul`,null,[c(`li`,null,`Minimal NASM x64 setup`),c(`li`,null,`GLFW window creation and management`),c(`li`,null,`Basic triangle rendering with OpenGL`),c(`li`,null,`Cross-platform ready (Windows/macOS/Linux)`)])],-1)]]),_:1})}}},zt=o({default:()=>Bt}),Bt={__name:`2026-04-17`,setup(t){let n={link:`https://www.linkedin.com/posts/leandroperes_computergraphics-raytracing-riow-ugcPost-7450638233287299073-wEmC`,meta:[]};return v({link:`https://www.linkedin.com/posts/leandroperes_computergraphics-raytracing-riow-ugcPost-7450638233287299073-wEmC`,meta:[]}),(t,r)=>{let a=X;return e(),l(a,{frontmatter:n},{default:i(()=>[...r[0]||=[c(`div`,{class:`prose m-auto slide-enter-content`},[c(`p`,null,[c(`strong`,null,`⨠Ported "Raytracing in One Weekend" straight to the PSP 3000`)])],-1)]]),_:1})}}},Q=Object.assign({"./2020-08-15.mp4":y,"./2020-12-16.mp4":x,"./2020-12-18.mp4":C,"./2021-04-14.mp4":T,"./2022-01-08.mp4":D,"./2022-08-11.mp4":k,"./2023-04-19.mp4":j,"./2023-07-28.mp4":N,"./2023-09-01.mp4":F,"./2023-09-13.mp4":L,"./2024-01-31.mp4":z,"./2024-04-22.mp4":V,"./2024-06-11.mp4":U,"./2024-09-01.mp4":G,"./2024-10-09.mp4":q,"./2024-11-11.mp4":Y,"./2024-11-12.mp4":oe,"./2025-03-04.mp4":ce,"./2025-06-05.mp4":ue,"./2025-06-11.mp4":fe,"./2025-07-03.mp4":me,"./2025-08-12.mp4":ge,"./2026-04-17.mp4":ve}),$=Object.assign({"./2024-02-22.gif":be,"./2025-03-14.jpeg":Se,"./2025-06-07.jpeg":we,"./2025-07-04.jpeg":Ee,"./2025-07-07.gif":Oe,"./2025-08-13.png":Ae}),Vt=Array.from(Object.entries(Object.assign({"./2020-08-15.md":Re,"./2020-12-16.md":Be,"./2020-12-18.md":He,"./202
11-04-14.md":We,"./2022-01-08.md":Ke,"./2022-08-11.md":Je,"./2023-04-19.md":Xe,"./2023-07-28.md":Qe,"./2023-09-01.md":et,"./2023-09-13.md":nt,"./2024-01-31.md":it,"./2024-02-22.md":ot,"./2024-04-22.md":ct,"./2024-06-11.md":ut,"./2024-09-01.md":ft,"./2024-10-09.md":mt,"./2024-11-11.md":gt,"./2024-11-12.md":vt,"./2025-03-04.md":bt,"./2025-03-14.md":St,"./2025-06-05.md":wt,"./2025-06-07.md":Et,"./2025-06-11.md":Ot,"./2025-07-03.md":At,"./2025-07-04.md":Mt,"./2025-07-07.md":Pt,"./2025-08-12.md":Z,"./2025-08-13.md":Lt,"./2026-04-17.md":zt}))).map(([e,t])=>{let n=e.slice(2,-3),r,i=Object.keys(Q).find(e=>e.startsWith(`./${n}.`)),a=Object.keys($).find(e=>e.startsWith(`./${n}.`));return i?r={type:`video`,content:Q[i].default}:a&&(r={type:`image`,content:$[a].default}),{date:n,comp:t.default,media:r}}).sort((e,t)=>t.date.localeCompare(e.date)),Ht={grid:`~ cols-1 lg:cols-2 xl:cols-3 gap-4`},Ut=s({__name:`ListLabs`,setup(t){let n=re(ne),i=h(()=>n.xl.value?3:n.lg.value?2:1),o=h(()=>{let e=Array.from({length:i.value},()=>[]);return Vt.forEach((t,n)=>{e[n%i.value].push(t)}),e});return(t,n)=>(e(),p(`div`,Ht,[(e(!0),p(f,null,r(o.value,(t,n)=>(e(),p(`div`,{key:n,flex:`~ col gap-4`},[(e(!0),p(f,null,r(t,({comp:t,date:r,media:i})=>(e(),l(d(t),{key:r,date:r,media:i,class:`slide-enter`,style:a({"--enter-stage":n+1})},null,8,[`date`,`media`,`style`]))),128))]))),128))]))}}),Wt={__name:`lab`,setup(t){let n={title:`Lab | Leandro Peres`,display:`Lab`,subtitle:`HandsâOn Experiments & Project Showcases`,description:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`,wrapperClass:`text-center`,image:`https://peres.dev/og/lab.png`,meta:[{property:`og:title`,content:`Lab | Leandro Peres`},{name:`twitter:title`,content:`Lab | Leandro Peres`},{name:`description`,content:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`},{property:`og:description`,content:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`},{name:`twitter:description`,content:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`},{property:`og:image`,content:`https://peres.dev/og/lab.png`},{name:`twitter:image`,content:`https://peres.dev/og/lab.png`},{name:`twitter:card`,content:`summary_large_image`}]};return v({title:`Lab | Leandro Peres`,meta:[{property:`og:title`,content:`Lab | Leandro Peres`},{name:`twitter:title`,content:`Lab | Leandro Peres`},{name:`description`,content:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`},{property:`og:description`,content:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`},{name:`twitter:description`,content:`A gallery of experiments, live demos and prototype updates - visual insights into my creative and technical journey`},{property:`og:image`,content:`https://peres.dev/og/lab.png`},{name:`twitter:image`,content:`https://peres.dev/og/lab.png`},{name:`twitter:card`,content:`summary_large_image`}]}),(t,r)=>{let a=Ut,o=g;return e(),l(o,{frontmatter:n},{default:i(()=>[c(`div`,null,[ee(a)])]),_:1})}}};export{Wt as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.