bloody-engine 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/node/index.js +400 -0
  2. package/dist/web/core/buffer.d.ts +58 -0
  3. package/dist/web/core/buffer.d.ts.map +1 -0
  4. package/dist/web/core/grahpic-device.d.ts +66 -0
  5. package/dist/web/core/grahpic-device.d.ts.map +1 -0
  6. package/dist/web/core/index.d.ts +8 -0
  7. package/dist/web/core/index.d.ts.map +1 -0
  8. package/dist/web/core/resource-loader-factory.d.ts +90 -0
  9. package/dist/web/core/resource-loader-factory.d.ts.map +1 -0
  10. package/dist/web/core/resource-loader.d.ts +71 -0
  11. package/dist/web/core/resource-loader.d.ts.map +1 -0
  12. package/dist/web/core/resource-pipeline.d.ts +139 -0
  13. package/dist/web/core/resource-pipeline.d.ts.map +1 -0
  14. package/dist/web/core/shader.d.ts +62 -0
  15. package/dist/web/core/shader.d.ts.map +1 -0
  16. package/dist/web/core/texture.d.ts +69 -0
  17. package/dist/web/core/texture.d.ts.map +1 -0
  18. package/dist/web/demo-node.d.ts +2 -0
  19. package/dist/web/demo-node.d.ts.map +1 -0
  20. package/dist/web/examples/batch-renderer-demo.d.ts +10 -0
  21. package/dist/web/examples/batch-renderer-demo.d.ts.map +1 -0
  22. package/dist/web/examples/projection-examples.d.ts +87 -0
  23. package/dist/web/examples/projection-examples.d.ts.map +1 -0
  24. package/dist/web/examples/resource-loader-demo.d.ts +14 -0
  25. package/dist/web/examples/resource-loader-demo.d.ts.map +1 -0
  26. package/dist/web/examples/shader-examples.d.ts +92 -0
  27. package/dist/web/examples/shader-examples.d.ts.map +1 -0
  28. package/dist/web/examples/sprite-batch-renderer-demo.d.ts +12 -0
  29. package/dist/web/examples/sprite-batch-renderer-demo.d.ts.map +1 -0
  30. package/dist/web/index.d.ts +7 -0
  31. package/dist/web/index.d.ts.map +1 -0
  32. package/dist/web/index.js +760 -474
  33. package/dist/web/index.umd.js +23 -23
  34. package/dist/web/platforms/browser/browser-context.d.ts +31 -0
  35. package/dist/web/platforms/browser/browser-context.d.ts.map +1 -0
  36. package/dist/web/platforms/browser/browser-resource-loader.d.ts +67 -0
  37. package/dist/web/platforms/browser/browser-resource-loader.d.ts.map +1 -0
  38. package/dist/web/platforms/node/node-context.d.ts +31 -0
  39. package/dist/web/platforms/node/node-context.d.ts.map +1 -0
  40. package/dist/web/platforms/node/node-resource-loader.d.ts +73 -0
  41. package/dist/web/platforms/node/node-resource-loader.d.ts.map +1 -0
  42. package/dist/web/platforms/node/sdl-window.d.ts +41 -0
  43. package/dist/web/platforms/node/sdl-window.d.ts.map +1 -0
  44. package/dist/web/projection.test.d.ts +5 -0
  45. package/dist/web/projection.test.d.ts.map +1 -0
  46. package/dist/web/public-api.d.ts +25 -0
  47. package/dist/web/public-api.d.ts.map +1 -0
  48. package/dist/web/rendering/batch-renderer.d.ts +273 -0
  49. package/dist/web/rendering/batch-renderer.d.ts.map +1 -0
  50. package/dist/web/rendering/camera.d.ts +153 -0
  51. package/dist/web/rendering/camera.d.ts.map +1 -0
  52. package/dist/web/rendering/projection.d.ts +108 -0
  53. package/dist/web/rendering/projection.d.ts.map +1 -0
  54. package/dist/web/rendering/rendering-context-factory.d.ts +24 -0
  55. package/dist/web/rendering/rendering-context-factory.d.ts.map +1 -0
  56. package/dist/web/rendering/rendering-context.d.ts +77 -0
  57. package/dist/web/rendering/rendering-context.d.ts.map +1 -0
  58. package/dist/web/rendering/vertex.d.ts +98 -0
  59. package/dist/web/rendering/vertex.d.ts.map +1 -0
  60. package/dist/web/scene/scene.d.ts +139 -0
  61. package/dist/web/scene/scene.d.ts.map +1 -0
  62. package/package.json +5 -4
@@ -1,21 +1,21 @@
1
- (function(l,C){typeof exports=="object"&&typeof module<"u"?C(exports,require("gl"),require("fs/promises"),require("path")):typeof define=="function"&&define.amd?define(["exports","gl","fs/promises","path"],C):(l=typeof globalThis<"u"?globalThis:l||self,C(l.BloodyEngine={},l.createGL,l.fs,l.path))})(this,(function(l,C,re,se){"use strict";function q(a){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const t in a)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(a,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>a[t]})}}return e.default=a,Object.freeze(e)}const T=q(re),p=q(se);class O{constructor(e){this.isBrowser=!0,e.canvas?this.canvas=e.canvas:(this.canvas=document.createElement("canvas"),document.body.appendChild(this.canvas)),this.width=e.width,this.height=e.height,this.canvas.width=this.width,this.canvas.height=this.height;const t={alpha:!1,...e.contextAttributes},r=this.canvas.getContext("webgl",t);if(!r)throw new Error("Failed to initialize WebGL context in browser");this.glContext=r}resize(e,t){this.width=e,this.height=t,this.canvas.width=e,this.canvas.height=t,this.glContext.viewport(0,0,e,t)}getViewport(){return{width:this.width,height:this.height}}clear(e){e&&this.glContext.clearColor(e.r,e.g,e.b,e.a),this.glContext.clear(this.glContext.COLOR_BUFFER_BIT|this.glContext.DEPTH_BUFFER_BIT)}present(){}dispose(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}}class V{constructor(e){this.isBrowser=!1,this.width=e.width,this.height=e.height;const t=C(this.width,this.height,{preserveDrawingBuffer:e.preserveDrawingBuffer??!0,...e.contextAttributes});if(!t)throw new Error("Failed to initialize WebGL context in Node.js");this.glContext=t}resize(e,t){this.width=e,this.height=t,console.warn("NodeRenderingContext: Resize requested but not supported. Consider recreating context.")}getViewport(){return{width:this.width,height:this.height}}clear(e){e&&this.glContext.clearColor(e.r,e.g,e.b,e.a),this.glContext.clear(this.glContext.COLOR_BUFFER_BIT|this.glContext.DEPTH_BUFFER_BIT)}present(){this.glContext.flush()}dispose(){this.glContext.flush()}readPixels(){const e=new Uint8Array(this.width*this.height*4);return this.glContext.readPixels(0,0,this.width,this.height,this.glContext.RGBA,this.glContext.UNSIGNED_BYTE,e),e}}class X{static isBrowserEnvironment(){return typeof window<"u"&&typeof document<"u"}static createContext(e){return this.isBrowserEnvironment()?new O(e):new V(e)}static createBrowserContext(e){return new O(e)}static createNodeContext(e){return new V(e)}}class k{constructor(e,t,r,s){this.gl=e;const i=this.injectPrecisionHeader(t,s),o=this.injectPrecisionHeader(r,s);this.vertexShader=this.compileShader(i,e.VERTEX_SHADER),this.fragmentShader=this.compileShader(o,e.FRAGMENT_SHADER),this.program=this.linkProgram(this.vertexShader,this.fragmentShader)}injectPrecisionHeader(e,t){return e.includes("#ifdef GL_ES")||e.includes("precision")?e:`#ifdef GL_ES
1
+ (function(l,_){typeof exports=="object"&&typeof module<"u"?_(exports,require("gl"),require("@kmamal/sdl"),require("fs/promises"),require("path")):typeof define=="function"&&define.amd?define(["exports","gl","@kmamal/sdl","fs/promises","path"],_):(l=typeof globalThis<"u"?globalThis:l||self,_(l.BloodyEngine={},l.createGL,l.sdl,l.fs,l.path))})(this,(function(l,_,re,ie,se){"use strict";function G(h){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(h){for(const t in h)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(h,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>h[t]})}}return e.default=h,Object.freeze(e)}const D=G(ie),L=G(se);class V{constructor(e){this.isBrowser=!0,e.canvas?this.canvas=e.canvas:(this.canvas=document.createElement("canvas"),document.body.appendChild(this.canvas)),this.width=e.width,this.height=e.height,this.canvas.width=this.width,this.canvas.height=this.height;const t={alpha:!1,...e.contextAttributes},r=this.canvas.getContext("webgl",t);if(!r)throw new Error("Failed to initialize WebGL context in browser");this.glContext=r}resize(e,t){this.width=e,this.height=t,this.canvas.width=e,this.canvas.height=t,this.glContext.viewport(0,0,e,t)}getViewport(){return{width:this.width,height:this.height}}clear(e){e&&this.glContext.clearColor(e.r,e.g,e.b,e.a),this.glContext.clear(this.glContext.COLOR_BUFFER_BIT|this.glContext.DEPTH_BUFFER_BIT)}present(){}dispose(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}}class Y{constructor(e){this.isBrowser=!1,this.width=e.width,this.height=e.height;const t=_(this.width,this.height,{preserveDrawingBuffer:e.preserveDrawingBuffer??!0,...e.contextAttributes});if(!t)throw new Error("Failed to initialize WebGL context in Node.js");this.glContext=t}resize(e,t){this.width=e,this.height=t,console.warn("NodeRenderingContext: Resize requested but not supported. Consider recreating context.")}getViewport(){return{width:this.width,height:this.height}}clear(e){e&&this.glContext.clearColor(e.r,e.g,e.b,e.a),this.glContext.clear(this.glContext.COLOR_BUFFER_BIT|this.glContext.DEPTH_BUFFER_BIT)}present(){this.glContext.flush()}dispose(){this.glContext.flush()}readPixels(){const e=new Uint8Array(this.width*this.height*4);return this.glContext.readPixels(0,0,this.width,this.height,this.glContext.RGBA,this.glContext.UNSIGNED_BYTE,e),e}}class W{static isBrowserEnvironment(){return typeof window<"u"&&typeof document<"u"}static createContext(e){return this.isBrowserEnvironment()?new V(e):new Y(e)}static createBrowserContext(e){return new V(e)}static createNodeContext(e){return new Y(e)}}class Q{constructor(e,t,r,i){this.gl=e;const s=this.injectPrecisionHeader(t,i),o=this.injectPrecisionHeader(r,i);this.vertexShader=this.compileShader(s,e.VERTEX_SHADER),this.fragmentShader=this.compileShader(o,e.FRAGMENT_SHADER),this.program=this.linkProgram(this.vertexShader,this.fragmentShader)}injectPrecisionHeader(e,t){return e.includes("#ifdef GL_ES")||e.includes("precision")?e:`#ifdef GL_ES
2
2
  precision highp float;
3
3
  #endif
4
- `+e}compileShader(e,t){const r=this.gl.createShader(t);if(!r)throw new Error(`Failed to create shader of type ${t}`);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS)){const i=this.gl.getShaderInfoLog(r),o=t===this.gl.VERTEX_SHADER?"vertex":"fragment";throw this.gl.deleteShader(r),new Error(`Failed to compile ${o} shader:
5
- ${i}
4
+ `+e}compileShader(e,t){const r=this.gl.createShader(t);if(!r)throw new Error(`Failed to create shader of type ${t}`);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS)){const s=this.gl.getShaderInfoLog(r),o=t===this.gl.VERTEX_SHADER?"vertex":"fragment";throw this.gl.deleteShader(r),new Error(`Failed to compile ${o} shader:
5
+ ${s}
6
6
 
7
7
  Source:
8
- ${e}`)}return r}linkProgram(e,t){const r=this.gl.createProgram();if(!r)throw new Error("Failed to create shader program");if(this.gl.attachShader(r,e),this.gl.attachShader(r,t),this.gl.linkProgram(r),!this.gl.getProgramParameter(r,this.gl.LINK_STATUS)){const i=this.gl.getProgramInfoLog(r);throw this.gl.deleteProgram(r),this.gl.deleteShader(e),this.gl.deleteShader(t),new Error(`Failed to link shader program:
9
- ${i}`)}return r}getProgram(){return this.program}getUniformLocation(e){return this.gl.getUniformLocation(this.program,e)}getAttributeLocation(e){return this.gl.getAttribLocation(this.program,e)}use(){this.gl.useProgram(this.program)}dispose(){this.gl.deleteProgram(this.program),this.gl.deleteShader(this.vertexShader),this.gl.deleteShader(this.fragmentShader)}}class H{constructor(e,t){this.context=X.createContext({width:e,height:t,preserveDrawingBuffer:!0})}getGLContext(){return this.context.glContext}getRenderingContext(){return this.context}getWidth(){return this.context.width}getHeight(){return this.context.height}getViewport(){return this.context.getViewport()}isBrowser(){return this.context.isBrowser}resize(e,t){this.context.resize(e,t)}clear(e){this.context.clear(e)}present(){this.context.present()}dispose(){this.context.dispose()}createShader(e,t){return new k(this.context.glContext,e,t,this.context.isBrowser)}}class R{constructor(e,t,r,s){this.gl=e,this.width=t,this.height=r;const i=e.createTexture();if(!i)throw new Error("Failed to create texture");this.texture=i,e.bindTexture(e.TEXTURE_2D,this.texture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),s?e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,r,0,e.RGBA,e.UNSIGNED_BYTE,s):e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,r,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindTexture(e.TEXTURE_2D,null)}static createSolid(e,t,r,s,i,o,n=255){const c=t*r,h=new Uint8Array(c*4);for(let m=0;m<c;m++){const u=m*4;h[u]=s,h[u+1]=i,h[u+2]=o,h[u+3]=n}return new R(e,t,r,h)}static createCheckerboard(e,t,r,s=32){const i=new Uint8Array(t*r*4);for(let o=0;o<r;o++)for(let n=0;n<t;n++){const c=Math.floor(n/s),h=Math.floor(o/s),m=(c+h)%2===0,u=(o*t+n)*4,f=m?255:0;i[u]=f,i[u+1]=f,i[u+2]=f,i[u+3]=255}return new R(e,t,r,i)}static createGradient(e,t,r){const s=new Uint8Array(t*r*4);for(let i=0;i<r;i++)for(let o=0;o<t;o++){const n=(i*t+o)*4;s[n]=Math.floor(o/t*255),s[n+1]=Math.floor(i/r*255),s[n+2]=128,s[n+3]=255}return new R(e,t,r,s)}bind(e=0){this.gl.activeTexture(this.gl.TEXTURE0+e),this.gl.bindTexture(this.gl.TEXTURE_2D,this.texture)}unbind(){this.gl.bindTexture(this.gl.TEXTURE_2D,null)}getHandle(){return this.texture}getDimensions(){return{width:this.width,height:this.height}}dispose(){this.gl.deleteTexture(this.texture)}}class W{constructor(e,t,r=0){this.gl=e,this.stride=r;const s=r>0?r/4:3;this.vertexCount=t.length/s;const i=e.createBuffer();if(!i)throw new Error("Failed to create vertex buffer");this.buffer=i,e.bindBuffer(e.ARRAY_BUFFER,this.buffer),e.bufferData(e.ARRAY_BUFFER,t,e.STATIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}bind(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.buffer)}unbind(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}getVertexCount(){return this.vertexCount}getStride(){return this.stride}dispose(){this.gl.deleteBuffer(this.buffer)}}class j{constructor(e,t){this.gl=e,this.indexCount=t.length;const r=e.createBuffer();if(!r)throw new Error("Failed to create index buffer");this.buffer=r,e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.buffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,t,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null)}bind(){this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.buffer)}unbind(){this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null)}getIndexCount(){return this.indexCount}dispose(){this.gl.deleteBuffer(this.buffer)}}const ie=Object.freeze(Object.defineProperty({__proto__:null,IndexBuffer:j,VertexBuffer:W},Symbol.toStringTag,{value:"Module"}));class oe{constructor(e,t,r=1e3){this.vertexBuffer=null,this.quads=[],this.isDirty=!1,this.verticesPerQuad=6,this.floatsPerVertex=5,this.texture=null,this.gl=e,this.shader=t,this.maxQuads=r;const s=r*this.verticesPerQuad*this.floatsPerVertex;this.vertexData=new Float32Array(s);const i=e.createBuffer();if(!i)throw new Error("Failed to create vertex buffer");this.vertexBuffer=i,e.bindBuffer(e.ARRAY_BUFFER,this.vertexBuffer),e.bufferData(e.ARRAY_BUFFER,this.vertexData.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}setTexture(e){this.texture=e}addQuad(e){if(this.quads.length>=this.maxQuads){console.warn(`Batch renderer at max capacity (${this.maxQuads})`);return}this.quads.push(e),this.isDirty=!0}clear(){this.quads=[],this.isDirty=!0}getQuadCount(){return this.quads.length}update(){if(!this.isDirty||this.quads.length===0)return;let e=0;for(const t of this.quads){const r=this.generateQuadVertices(t);for(const s of r)this.vertexData[e++]=s[0],this.vertexData[e++]=s[1],this.vertexData[e++]=s[2],this.vertexData[e++]=s[3],this.vertexData[e++]=s[4]}this.vertexBuffer&&(this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertexData.subarray(0,e)),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)),this.isDirty=!1}render(e){if(this.quads.length!==0&&(this.update(),this.shader.use(),this.vertexBuffer)){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);const t=this.shader.getAttributeLocation("aPosition"),r=this.shader.getAttributeLocation("aTexCoord");if(t!==-1&&(this.gl.enableVertexAttribArray(t),this.gl.vertexAttribPointer(t,3,this.gl.FLOAT,!1,this.floatsPerVertex*4,0)),r!==-1&&(this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,this.floatsPerVertex*4,12)),this.texture){this.texture.bind(0);const o=this.shader.getUniformLocation("uTexture");o!==null&&this.gl.uniform1i(o,0)}const s=this.shader.getUniformLocation("uMatrix");if(s!==null){const o=e?e.getViewMatrix():new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);this.gl.uniformMatrix4fv(s,!1,o)}const i=this.quads.length*this.verticesPerQuad;this.gl.drawArrays(this.gl.TRIANGLES,0,i),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}}generateQuadVertices(e){const{x:t,y:r,width:s,height:i,rotation:o}=e,n=s/2,c=i/2,h=Math.cos(o),m=Math.sin(o),u=(v,b)=>[v*h-b*m,v*m+b*h],f=[[-n,-c],[n,-c],[n,c],[n,c],[-n,c],[-n,-c]],g=[[0,0],[1,0],[1,1],[1,1],[0,1],[0,0]],E=[];for(let v=0;v<f.length;v++){const[b,_]=f[v],[F,d]=u(b,_),[w,y]=g[v];E.push([t+F,r+d,0,w,y])}return E}dispose(){this.vertexBuffer&&(this.gl.deleteBuffer(this.vertexBuffer),this.vertexBuffer=null)}}class ne{constructor(e,t,r=1e3){this.vertexBuffer=null,this.quads=[],this.isDirty=!1,this.verticesPerQuad=6,this.floatsPerVertex=10,this.texture=null,this.depthTestEnabled=!0,this.gl=e,this.shader=t,this.maxQuads=r;const s=r*this.verticesPerQuad*this.floatsPerVertex;this.vertexData=new Float32Array(s);const i=e.createBuffer();if(!i)throw new Error("Failed to create vertex buffer");this.vertexBuffer=i,e.bindBuffer(e.ARRAY_BUFFER,this.vertexBuffer),e.bufferData(e.ARRAY_BUFFER,this.vertexData.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}setTexture(e){this.texture=e}addQuad(e){if(this.quads.length>=this.maxQuads){console.warn(`Sprite batch renderer at max capacity (${this.maxQuads})`);return}this.quads.push(e),this.isDirty=!0}clear(){this.quads=[],this.isDirty=!0}getQuadCount(){return this.quads.length}update(){if(!this.isDirty||this.quads.length===0)return;let e=0;for(const t of this.quads){const{x:r,y:s,z:i=0,width:o,height:n,rotation:c,color:h={r:1,g:1,b:1,a:1},uvRect:m={uMin:0,vMin:0,uMax:1,vMax:1},texIndex:u=0}=t,f=this.generateQuadVertices({x:r,y:s,z:i,width:o,height:n,rotation:c,color:h,uvRect:m,texIndex:u});for(const g of f)this.vertexData[e++]=g.x,this.vertexData[e++]=g.y,this.vertexData[e++]=g.z,this.vertexData[e++]=g.u,this.vertexData[e++]=g.v,this.vertexData[e++]=g.r,this.vertexData[e++]=g.g,this.vertexData[e++]=g.b,this.vertexData[e++]=g.a,this.vertexData[e++]=g.texIndex}this.vertexBuffer&&(this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertexData.subarray(0,e)),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)),this.isDirty=!1}setDepthTestEnabled(e){this.depthTestEnabled=e}render(e){if(this.quads.length!==0&&(this.update(),this.shader.use(),this.depthTestEnabled?(this.gl.enable(this.gl.DEPTH_TEST),this.gl.depthFunc(this.gl.LEQUAL)):this.gl.disable(this.gl.DEPTH_TEST),this.vertexBuffer)){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);const t=this.shader.getAttributeLocation("aPosition"),r=this.shader.getAttributeLocation("aTexCoord"),s=this.shader.getAttributeLocation("aColor"),i=this.shader.getAttributeLocation("aTexIndex"),o=this.floatsPerVertex*4;if(t!==-1&&(this.gl.enableVertexAttribArray(t),this.gl.vertexAttribPointer(t,3,this.gl.FLOAT,!1,o,0)),r!==-1&&(this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,o,12)),s!==-1&&(this.gl.enableVertexAttribArray(s),this.gl.vertexAttribPointer(s,4,this.gl.FLOAT,!1,o,20)),i!==-1&&(this.gl.enableVertexAttribArray(i),this.gl.vertexAttribPointer(i,1,this.gl.FLOAT,!1,o,36)),this.texture){this.texture.bind(0);const h=this.shader.getUniformLocation("uTexture");h!==null&&this.gl.uniform1i(h,0)}const n=this.shader.getUniformLocation("uMatrix");if(n!==null){const h=e?e.getViewMatrix():new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);this.gl.uniformMatrix4fv(n,!1,h)}const c=this.quads.length*this.verticesPerQuad;this.gl.drawArrays(this.gl.TRIANGLES,0,c),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}}generateQuadVertices(e){const{x:t,y:r,z:s,width:i,height:o,rotation:n,color:c,uvRect:h,texIndex:m}=e,u=i/2,f=o/2,g=Math.cos(n),E=Math.sin(n),v=(d,w)=>[d*g-w*E,d*E+w*g],b=[[-u,-f],[u,-f],[u,f],[u,f],[-u,f],[-u,-f]],_=[[h.uMin,h.vMin],[h.uMax,h.vMin],[h.uMax,h.vMax],[h.uMax,h.vMax],[h.uMin,h.vMax],[h.uMin,h.vMin]],F=[];for(let d=0;d<b.length;d++){const[w,y]=b[d],[D,I]=v(w,y),[N,x]=_[d];F.push({x:t+D,y:r+I,z:s,u:N,v:x,r:c.r,g:c.g,b:c.b,a:c.a,texIndex:m})}return F}dispose(){this.vertexBuffer&&(this.gl.deleteBuffer(this.vertexBuffer),this.vertexBuffer=null)}}class A{static identity(){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}static translation(e,t,r=0){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,e,t,r,1])}static scale(e,t,r=1){return new Float32Array([e,0,0,0,0,t,0,0,0,0,r,0,0,0,0,1])}static multiply(e,t){const r=new Float32Array(16);for(let s=0;s<4;s++)for(let i=0;i<4;i++){let o=0;for(let n=0;n<4;n++)o+=e[n*4+i]*t[s*4+n];r[s*4+i]=o}return r}static createViewMatrix(e,t,r){const s=A.translation(-e,-t,0),i=A.scale(r,r,1);return A.multiply(s,i)}}class ae{constructor(e=0,t=0,r=1){this._viewMatrix=null,this._viewMatrixDirty=!0,this._x=e,this._y=t,this._zoom=r}get x(){return this._x}set x(e){this._x=e,this._viewMatrixDirty=!0}get y(){return this._y}set y(e){this._y=e,this._viewMatrixDirty=!0}get zoom(){return this._zoom}set zoom(e){this._zoom=Math.max(.001,e),this._viewMatrixDirty=!0}setPosition(e,t){this._x=e,this._y=t,this._viewMatrixDirty=!0}move(e,t){this._x+=e,this._y+=t,this._viewMatrixDirty=!0}zoomBy(e){this._zoom=Math.max(.001,this._zoom*e),this._viewMatrixDirty=!0}reset(){this._x=0,this._y=0,this._zoom=1,this._viewMatrixDirty=!0}getViewMatrix(){return(this._viewMatrixDirty||this._viewMatrix===null)&&(this._viewMatrix=A.createViewMatrix(this._x,this._y,this._zoom),this._viewMatrixDirty=!1),this._viewMatrix}screenToWorld(e,t,r,s){const i=e-r/2,o=t-s/2,n=i/this._zoom+this._x,c=o/this._zoom+this._y;return{x:n,y:c}}worldToScreen(e,t,r,s){const i=(e-this._x)*this._zoom,o=(t-this._y)*this._zoom,n=i+r/2,c=o+s/2;return{x:n,y:c}}}class Q{constructor(e="",t=1e4){this.baseUrl=e||this.getCurrentOrigin(),this.defaultTimeout=t}getCurrentOrigin(){return typeof window<"u"?window.location.origin:"http://localhost"}resolvePath(e){try{return e.startsWith("http://")||e.startsWith("https://")?e:e.startsWith("//")?window.location.protocol+e:e.startsWith("/")?this.baseUrl+e:`${this.baseUrl}/${e}`}catch{return e}}async load(e,t){const r=this.resolvePath(e);try{const s={credentials:t?.credentials||"same-origin"};t?.headers&&(s.headers=t.headers);const i=new AbortController,o=setTimeout(()=>i.abort(),this.defaultTimeout);s.signal=i.signal;const n=await fetch(r,s);if(clearTimeout(o),!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText} for URL: ${r}`);return await n.text()}catch(s){throw s instanceof Error?s.name==="AbortError"?new Error(`Request timeout after ${this.defaultTimeout}ms for URL: ${r}`):new Error(`Failed to load resource from ${r}: ${s.message}`):new Error(`Failed to load resource from ${r}: Unknown error`)}}async loadMultiple(e,t){const r=e.map(async s=>{try{return{data:await this.load(s,t),path:s,success:!0}}catch(i){return{data:"",path:s,success:!1,error:i instanceof Error?i.message:String(i)}}});return Promise.all(r)}canLoad(e){const t=[/^https?:\/\//i,/^\/\//,/^\//,/^\.\.?\//],r=/\.[a-z0-9]+$/i.test(e);return t.some(s=>s.test(e))||r}setBaseUrl(e){this.baseUrl=e}getBaseUrl(){return this.baseUrl}setTimeout(e){this.defaultTimeout=e}}const ce=Object.freeze(Object.defineProperty({__proto__:null,BrowserResourceLoader:Q},Symbol.toStringTag,{value:"Module"}));class K{constructor(e=process.cwd()){this.baseDir=e}resolvePath(e){return p.isAbsolute(e)?p.normalize(e):p.normalize(p.join(this.baseDir,e))}async load(e,t){const r=this.resolvePath(e),s=t?.encoding||"utf-8";try{return await T.readFile(r,s)}catch(i){if(i instanceof Error){const o=i.code;throw o==="ENOENT"?new Error(`File not found: ${r} (resolved from: ${e})`):o==="EACCES"?new Error(`Permission denied reading file: ${r}`):o==="EISDIR"?new Error(`Path is a directory, not a file: ${r}`):new Error(`Failed to load resource from ${r}: ${i.message}`)}throw new Error(`Failed to load resource from ${r}: Unknown error`)}}async loadMultiple(e,t){const r=e.map(async s=>{try{return{data:await this.load(s,t),path:s,success:!0}}catch(i){return{data:"",path:s,success:!1,error:i instanceof Error?i.message:String(i)}}});return Promise.all(r)}canLoad(e){return[/^\//,/^[a-zA-Z]:/,/^\.\.?\//,/^[^/\\]+\//].some(r=>r.test(e))}async exists(e){const t=this.resolvePath(e);try{return await T.access(t,T.constants.F_OK),!0}catch{return!1}}async getStats(e){const t=this.resolvePath(e);return T.stat(t)}setBaseDir(e){this.baseDir=e}getBaseDir(){return this.baseDir}async listDirectory(e,t=!1){const r=this.resolvePath(e),s=await T.readdir(r,{withFileTypes:!0}),i=[];for(const o of s){const n=p.join(r,o.name);if(o.isDirectory()&&t){const c=await this.listDirectory(n,!0);i.push(...c)}else o.isFile()&&i.push(n)}return i}}const he=Object.freeze(Object.defineProperty({__proto__:null,NodeResourceLoader:K},Symbol.toStringTag,{value:"Module"}));var P=(a=>(a.BROWSER="browser",a.NODE="node",a.UNKNOWN="unknown",a))(P||{});class S{static detectEnvironment(){return typeof window<"u"&&typeof window.document<"u"&&typeof fetch<"u"?"browser":typeof process<"u"&&process.versions!=null&&process.versions.node!=null?"node":"unknown"}static isBrowser(){return this.detectEnvironment()==="browser"}static isNode(){return this.detectEnvironment()==="node"}static async create(e){const t=e?.forceEnvironment||this.detectEnvironment();switch(t){case"browser":return await this.createBrowserLoader(e);case"node":return await this.createNodeLoader(e);case"unknown":throw new Error("Unsupported environment: Unable to determine runtime environment. Please specify forceEnvironment in options.");default:throw new Error(`Unsupported environment: ${t}`)}}static async createBrowserLoader(e){const{BrowserResourceLoader:t}=await Promise.resolve().then(()=>ce);return new t(e?.baseUrl,e?.timeout)}static async createNodeLoader(e){const{NodeResourceLoader:t}=await Promise.resolve().then(()=>he);return new t(e?.baseDir)}static async createWithFallback(e,t){try{return t={...t,forceEnvironment:e},await this.create(t)}catch{return await this.create({...t,forceEnvironment:void 0})}}}async function J(a){return await S.create(a)}const le=Object.freeze(Object.defineProperty({__proto__:null,Environment:P,ResourceLoaderFactory:S,createResourceLoader:J},Symbol.toStringTag,{value:"Module"}));class ue{constructor(e=!0){this.cache=new Map,this.enabled=e}get(e){if(this.enabled)return this.cache.get(e)}set(e,t){this.enabled&&this.cache.set(e,t)}has(e){return this.enabled?this.cache.has(e):!1}clear(){this.cache.clear()}size(){return this.cache.size}enable(){this.enabled=!0}disable(){this.enabled=!1}}class Z{constructor(e,t){this.loader=e,this.concurrency=t?.concurrency??10,this.cache=new ue(t?.cache??!0)}async load(e,t){const r=this.cache.get(e);if(r!==void 0)return r;const s=await this.loader.load(e,t);return this.cache.set(e,s),s}async loadBatch(e,t){const r=new Map,s=new Map;for(let i=0;i<e.length;i+=this.concurrency){const o=e.slice(i,i+this.concurrency),n=await this.loader.loadMultiple(o,t);for(const c of n)c.success?(r.set(c.path,c.data),this.cache.set(c.path,c.data)):s.set(c.path,c.error||"Unknown error")}return{succeeded:r,failed:s,total:e.length,successCount:r.size,failureCount:s.size}}async loadShader(e,t,r){const[s,i]=await Promise.all([this.load(e,r),this.load(t,r)]);return{vertex:s,fragment:i}}async loadShaders(e,t){return await Promise.all(e.map(async s=>{const i=await this.loadShader(s.vertex,s.fragment,t);return{name:s.name,...i}}))}async loadFromManifest(e,t){const r=await this.load(e,t),s=JSON.parse(r);return this.loadBatch(s.resources,t)}async preload(e,t){await this.loadBatch(e,t)}isCached(e){return this.cache.has(e)}getCached(e){return this.cache.get(e)}clearCache(){this.cache.clear()}getCacheSize(){return this.cache.size()}enableCache(){this.cache.enable()}disableCache(){this.cache.disable()}setConcurrency(e){this.concurrency=Math.max(1,e)}getLoader(){return this.loader}}async function ee(a){const{ResourceLoaderFactory:e}=await Promise.resolve().then(()=>le),t=await e.create({baseUrl:a?.baseUrl,baseDir:a?.baseDir,timeout:a?.timeout});return new Z(t,a)}const U={width:800,height:600},M={quad:{vertices:new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,.5,.5,0,1,1,-.5,.5,0,0,1,-.5,-.5,0,0,0]),stride:20}},$={size:256},z={shaders:[{name:"basic",vertex:"resources/shaders/basic.vert",fragment:"resources/shaders/basic.frag"},{name:"glow",vertex:"resources/shaders/glow.vert",fragment:"resources/shaders/glow.frag"}],resources:["resources/shaders/basic.vert","resources/shaders/basic.frag","resources/shaders/glow.vert","resources/shaders/glow.frag"]};async function de(){console.log("🩸 Bloody Engine - Resource Loader Demo"),console.log(`==========================================
10
- `);const a=S.detectEnvironment();if(console.log(`✓ Environment detected: ${a}`),a!==P.BROWSER){console.warn("⚠ This demo is designed for browser environment");return}console.log(`
8
+ ${e}`)}return r}linkProgram(e,t){const r=this.gl.createProgram();if(!r)throw new Error("Failed to create shader program");if(this.gl.attachShader(r,e),this.gl.attachShader(r,t),this.gl.linkProgram(r),!this.gl.getProgramParameter(r,this.gl.LINK_STATUS)){const s=this.gl.getProgramInfoLog(r);throw this.gl.deleteProgram(r),this.gl.deleteShader(e),this.gl.deleteShader(t),new Error(`Failed to link shader program:
9
+ ${s}`)}return r}getProgram(){return this.program}getUniformLocation(e){return this.gl.getUniformLocation(this.program,e)}getAttributeLocation(e){return this.gl.getAttribLocation(this.program,e)}use(){this.gl.useProgram(this.program)}dispose(){this.gl.deleteProgram(this.program),this.gl.deleteShader(this.vertexShader),this.gl.deleteShader(this.fragmentShader)}}class X{constructor(e,t){this.context=W.createContext({width:e,height:t,preserveDrawingBuffer:!0})}getGLContext(){return this.context.glContext}getRenderingContext(){return this.context}getWidth(){return this.context.width}getHeight(){return this.context.height}getViewport(){return this.context.getViewport()}isBrowser(){return this.context.isBrowser}resize(e,t){this.context.resize(e,t)}clear(e){this.context.clear(e)}present(){this.context.present()}dispose(){this.context.dispose()}createShader(e,t){return new Q(this.context.glContext,e,t,this.context.isBrowser)}}class oe{constructor(e,t,r="Bloody Engine"){this.closed=!1,this.width=e,this.height=t,this.title=r;try{if(this.window=re.video.createWindow({width:this.width,height:this.height,title:this.title}),!this.window)throw new Error("Failed to create SDL window");this.window.on("close",()=>{this.closed=!0}),console.log(`✓ SDL Window created (${e}x${t}): "${r}"`)}catch(i){throw this.cleanup(),new Error(`Window creation failed: ${i}`)}}getDimensions(){return{width:this.width,height:this.height}}updatePixels(e){if(!(!this.window||this.closed))try{const t=Buffer.from(e),r=this.width*4;this.window.render(this.width,this.height,r,"rgba32",t)}catch(t){console.error("Failed to update pixels:",t)}}on(e,t){if(!(!this.window||this.closed))try{this.window.on(e,r=>{try{t(r)}catch(i){console.error(`Error in ${e} handler:`,i)}})}catch(r){console.error(`Error registering ${e} handler:`,r)}}isOpen(){return this.window!==null&&!this.closed}cleanup(){if(this.window&&!this.closed){try{this.window.destroy()}catch(e){console.warn("Error destroying window:",e)}this.window=null,this.closed=!0}console.log("✓ SDL Window cleaned up")}destroy(){this.cleanup()}}class T{constructor(e,t,r,i){this.gl=e,this.width=t,this.height=r;const s=e.createTexture();if(!s)throw new Error("Failed to create texture");this.texture=s,e.bindTexture(e.TEXTURE_2D,this.texture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),i?e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,r,0,e.RGBA,e.UNSIGNED_BYTE,i):e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,r,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindTexture(e.TEXTURE_2D,null)}static createSolid(e,t,r,i,s,o,n=255){const a=t*r,c=new Uint8Array(a*4);for(let x=0;x<a;x++){const u=x*4;c[u]=i,c[u+1]=s,c[u+2]=o,c[u+3]=n}return new T(e,t,r,c)}static createCheckerboard(e,t,r,i=32){const s=new Uint8Array(t*r*4);for(let o=0;o<r;o++)for(let n=0;n<t;n++){const a=Math.floor(n/i),c=Math.floor(o/i),x=(a+c)%2===0,u=(o*t+n)*4,g=x?255:0;s[u]=g,s[u+1]=g,s[u+2]=g,s[u+3]=255}return new T(e,t,r,s)}static createGradient(e,t,r){const i=new Uint8Array(t*r*4);for(let s=0;s<r;s++)for(let o=0;o<t;o++){const n=(s*t+o)*4;i[n]=Math.floor(o/t*255),i[n+1]=Math.floor(s/r*255),i[n+2]=128,i[n+3]=255}return new T(e,t,r,i)}bind(e=0){this.gl.activeTexture(this.gl.TEXTURE0+e),this.gl.bindTexture(this.gl.TEXTURE_2D,this.texture)}unbind(){this.gl.bindTexture(this.gl.TEXTURE_2D,null)}getHandle(){return this.texture}getDimensions(){return{width:this.width,height:this.height}}dispose(){this.gl.deleteTexture(this.texture)}}class k{constructor(e,t,r=0){this.gl=e,this.stride=r;const i=r>0?r/4:3;this.vertexCount=t.length/i;const s=e.createBuffer();if(!s)throw new Error("Failed to create vertex buffer");this.buffer=s,e.bindBuffer(e.ARRAY_BUFFER,this.buffer),e.bufferData(e.ARRAY_BUFFER,t,e.STATIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}bind(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.buffer)}unbind(){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}getVertexCount(){return this.vertexCount}getStride(){return this.stride}dispose(){this.gl.deleteBuffer(this.buffer)}}class H{constructor(e,t){this.gl=e,this.indexCount=t.length;const r=e.createBuffer();if(!r)throw new Error("Failed to create index buffer");this.buffer=r,e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.buffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,t,e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null)}bind(){this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.buffer)}unbind(){this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,null)}getIndexCount(){return this.indexCount}dispose(){this.gl.deleteBuffer(this.buffer)}}const ne=Object.freeze(Object.defineProperty({__proto__:null,IndexBuffer:H,VertexBuffer:k},Symbol.toStringTag,{value:"Module"}));class ae{constructor(e,t,r=1e3){this.vertexBuffer=null,this.quads=[],this.isDirty=!1,this.verticesPerQuad=6,this.floatsPerVertex=5,this.texture=null,this.gl=e,this.shader=t,this.maxQuads=r;const i=r*this.verticesPerQuad*this.floatsPerVertex;this.vertexData=new Float32Array(i);const s=e.createBuffer();if(!s)throw new Error("Failed to create vertex buffer");this.vertexBuffer=s,e.bindBuffer(e.ARRAY_BUFFER,this.vertexBuffer),e.bufferData(e.ARRAY_BUFFER,this.vertexData.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}setTexture(e){this.texture=e}addQuad(e){if(this.quads.length>=this.maxQuads){console.warn(`Batch renderer at max capacity (${this.maxQuads})`);return}this.quads.push(e),this.isDirty=!0}clear(){this.quads=[],this.isDirty=!0}getQuadCount(){return this.quads.length}update(){if(!this.isDirty||this.quads.length===0)return;let e=0;for(const t of this.quads){const r=this.generateQuadVertices(t);for(const i of r)this.vertexData[e++]=i[0],this.vertexData[e++]=i[1],this.vertexData[e++]=i[2],this.vertexData[e++]=i[3],this.vertexData[e++]=i[4]}this.vertexBuffer&&(this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertexData.subarray(0,e)),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)),this.isDirty=!1}render(e){if(this.quads.length!==0&&(this.update(),this.shader.use(),this.vertexBuffer)){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);const t=this.shader.getAttributeLocation("aPosition"),r=this.shader.getAttributeLocation("aTexCoord");if(t!==-1&&(this.gl.enableVertexAttribArray(t),this.gl.vertexAttribPointer(t,3,this.gl.FLOAT,!1,this.floatsPerVertex*4,0)),r!==-1&&(this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,this.floatsPerVertex*4,12)),this.texture){this.texture.bind(0);const o=this.shader.getUniformLocation("uTexture");o!==null&&this.gl.uniform1i(o,0)}const i=this.shader.getUniformLocation("uMatrix");if(i!==null){const o=e?e.getViewMatrix():new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);this.gl.uniformMatrix4fv(i,!1,o)}const s=this.quads.length*this.verticesPerQuad;this.gl.drawArrays(this.gl.TRIANGLES,0,s),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}}generateQuadVertices(e){const{x:t,y:r,width:i,height:s,rotation:o}=e,n=i/2,a=s/2,c=Math.cos(o),x=Math.sin(o),u=(w,m)=>[w*c-m*x,w*x+m*c],g=[[-n,-a],[n,-a],[n,a],[n,a],[-n,a],[-n,-a]],f=[[0,0],[1,0],[1,1],[1,1],[0,1],[0,0]],A=[];for(let w=0;w<g.length;w++){const[m,R]=g[w],[E,d]=u(m,R),[b,y]=f[w];A.push([t+E,r+d,0,b,y])}return A}dispose(){this.vertexBuffer&&(this.gl.deleteBuffer(this.vertexBuffer),this.vertexBuffer=null)}}class he{constructor(e,t,r=1e3){this.vertexBuffer=null,this.quads=[],this.isDirty=!1,this.verticesPerQuad=6,this.floatsPerVertex=10,this.texture=null,this.depthTestEnabled=!0,this.gl=e,this.shader=t,this.maxQuads=r;const i=r*this.verticesPerQuad*this.floatsPerVertex;this.vertexData=new Float32Array(i);const s=e.createBuffer();if(!s)throw new Error("Failed to create vertex buffer");this.vertexBuffer=s,e.bindBuffer(e.ARRAY_BUFFER,this.vertexBuffer),e.bufferData(e.ARRAY_BUFFER,this.vertexData.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}setTexture(e){this.texture=e}addQuad(e){if(this.quads.length>=this.maxQuads){console.warn(`Sprite batch renderer at max capacity (${this.maxQuads})`);return}this.quads.push(e),this.isDirty=!0}clear(){this.quads=[],this.isDirty=!0}getQuadCount(){return this.quads.length}update(){if(!this.isDirty||this.quads.length===0)return;let e=0;for(const t of this.quads){const{x:r,y:i,z:s=0,width:o,height:n,rotation:a,color:c={r:1,g:1,b:1,a:1},uvRect:x={uMin:0,vMin:0,uMax:1,vMax:1},texIndex:u=0}=t,g=this.generateQuadVertices({x:r,y:i,z:s,width:o,height:n,rotation:a,color:c,uvRect:x,texIndex:u});for(const f of g)this.vertexData[e++]=f.x,this.vertexData[e++]=f.y,this.vertexData[e++]=f.z,this.vertexData[e++]=f.u,this.vertexData[e++]=f.v,this.vertexData[e++]=f.r,this.vertexData[e++]=f.g,this.vertexData[e++]=f.b,this.vertexData[e++]=f.a,this.vertexData[e++]=f.texIndex}this.vertexBuffer&&(this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertexData.subarray(0,e)),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)),this.isDirty=!1}setDepthTestEnabled(e){this.depthTestEnabled=e}render(e){if(this.quads.length!==0&&(this.update(),this.shader.use(),this.depthTestEnabled?(this.gl.enable(this.gl.DEPTH_TEST),this.gl.depthFunc(this.gl.LEQUAL)):this.gl.disable(this.gl.DEPTH_TEST),this.vertexBuffer)){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);const t=this.shader.getAttributeLocation("aPosition"),r=this.shader.getAttributeLocation("aTexCoord"),i=this.shader.getAttributeLocation("aColor"),s=this.shader.getAttributeLocation("aTexIndex"),o=this.floatsPerVertex*4;if(t!==-1&&(this.gl.enableVertexAttribArray(t),this.gl.vertexAttribPointer(t,3,this.gl.FLOAT,!1,o,0)),r!==-1&&(this.gl.enableVertexAttribArray(r),this.gl.vertexAttribPointer(r,2,this.gl.FLOAT,!1,o,12)),i!==-1&&(this.gl.enableVertexAttribArray(i),this.gl.vertexAttribPointer(i,4,this.gl.FLOAT,!1,o,20)),s!==-1&&(this.gl.enableVertexAttribArray(s),this.gl.vertexAttribPointer(s,1,this.gl.FLOAT,!1,o,36)),this.texture){this.texture.bind(0);const c=this.shader.getUniformLocation("uTexture");c!==null&&this.gl.uniform1i(c,0)}const n=this.shader.getUniformLocation("uMatrix");if(n!==null){const c=e?e.getViewMatrix():new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);this.gl.uniformMatrix4fv(n,!1,c)}const a=this.quads.length*this.verticesPerQuad;this.gl.drawArrays(this.gl.TRIANGLES,0,a),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}}generateQuadVertices(e){const{x:t,y:r,z:i,width:s,height:o,rotation:n,color:a,uvRect:c,texIndex:x}=e,u=s/2,g=o/2,f=Math.cos(n),A=Math.sin(n),w=(d,b)=>[d*f-b*A,d*A+b*f],m=[[-u,-g],[u,-g],[u,g],[u,g],[-u,g],[-u,-g]],R=[[c.uMin,c.vMin],[c.uMax,c.vMin],[c.uMax,c.vMax],[c.uMax,c.vMax],[c.uMin,c.vMax],[c.uMin,c.vMin]],E=[];for(let d=0;d<m.length;d++){const[b,y]=m[d],[B,p]=w(b,y),[O,v]=R[d];E.push({x:t+B,y:r+p,z:i,u:O,v,r:a.r,g:a.g,b:a.b,a:a.a,texIndex:x})}return E}dispose(){this.vertexBuffer&&(this.gl.deleteBuffer(this.vertexBuffer),this.vertexBuffer=null)}}class ce{constructor(e,t,r=1e3,i={width:64,height:32},s=1){this.vertexBuffer=null,this.quads=[],this.isDirty=!1,this.verticesPerQuad=6,this.floatsPerVertex=12,this.texture=null,this.depthTestEnabled=!0,this.gl=e,this.shader=t,this.maxQuads=r,this.tileSize=i,this.zScale=s,this.resolution={width:e.canvas.width,height:e.canvas.height};const o=r*this.verticesPerQuad*this.floatsPerVertex;this.vertexData=new Float32Array(o);const n=e.createBuffer();if(!n)throw new Error("Failed to create vertex buffer");this.vertexBuffer=n,e.bindBuffer(e.ARRAY_BUFFER,this.vertexBuffer),e.bufferData(e.ARRAY_BUFFER,this.vertexData.byteLength,e.DYNAMIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null)}setTexture(e){this.texture=e}addQuad(e){if(this.quads.length>=this.maxQuads){console.warn(`Sprite batch renderer at max capacity (${this.maxQuads})`);return}this.quads.push(e),this.isDirty=!0}clear(){this.quads=[],this.isDirty=!0}getQuadCount(){return this.quads.length}update(){if(!this.isDirty||this.quads.length===0)return;let e=0;for(const t of this.quads){const{x:r,y:i,z:s=0,width:o,height:n,color:a={r:1,g:1,b:1,a:1},uvRect:c={uMin:0,vMin:0,uMax:1,vMax:1},texIndex:x=0,gridX:u,gridY:g}=t;let f,A;u!==void 0&&g!==void 0?(f=u,A=g):(f=(r/(this.tileSize.width*.5)+i/(this.tileSize.height*.5))*.5,A=(i/(this.tileSize.height*.5)-r/(this.tileSize.width*.5))*.5);const w=o/2,m=n/2,R=[[-w,-m],[w,-m],[w,m],[w,m],[-m,m],[-w,-m]],E=[[c.uMin,c.vMin],[c.uMax,c.vMin],[c.uMax,c.vMax],[c.uMax,c.vMax],[c.uMin,c.vMax],[c.uMin,c.vMin]];for(let d=0;d<R.length;d++){const[b,y]=R[d],[B,p]=E[d];this.vertexData[e++]=f,this.vertexData[e++]=A,this.vertexData[e++]=s,this.vertexData[e++]=b,this.vertexData[e++]=y,this.vertexData[e++]=B,this.vertexData[e++]=p,this.vertexData[e++]=a.r,this.vertexData[e++]=a.g,this.vertexData[e++]=a.b,this.vertexData[e++]=a.a,this.vertexData[e++]=x}}this.vertexBuffer&&(this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,this.vertexData.subarray(0,e)),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)),this.isDirty=!1}setDepthTestEnabled(e){this.depthTestEnabled=e}render(e){if(this.quads.length!==0&&(this.update(),this.shader.use(),this.depthTestEnabled?(this.gl.enable(this.gl.DEPTH_TEST),this.gl.depthFunc(this.gl.LEQUAL)):this.gl.disable(this.gl.DEPTH_TEST),this.vertexBuffer)){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuffer);const t=this.floatsPerVertex*4,r={gridPosition:this.shader.getAttributeLocation("aGridPosition"),zPosition:this.shader.getAttributeLocation("aZPosition"),localOffset:this.shader.getAttributeLocation("aLocalOffset"),texCoord:this.shader.getAttributeLocation("aTexCoord"),color:this.shader.getAttributeLocation("aColor"),texIndex:this.shader.getAttributeLocation("aTexIndex")};if(r.gridPosition!==-1&&(this.gl.enableVertexAttribArray(r.gridPosition),this.gl.vertexAttribPointer(r.gridPosition,2,this.gl.FLOAT,!1,t,0)),r.zPosition!==-1&&(this.gl.enableVertexAttribArray(r.zPosition),this.gl.vertexAttribPointer(r.zPosition,1,this.gl.FLOAT,!1,t,8)),r.localOffset!==-1&&(this.gl.enableVertexAttribArray(r.localOffset),this.gl.vertexAttribPointer(r.localOffset,2,this.gl.FLOAT,!1,t,12)),r.texCoord!==-1&&(this.gl.enableVertexAttribArray(r.texCoord),this.gl.vertexAttribPointer(r.texCoord,2,this.gl.FLOAT,!1,t,20)),r.color!==-1&&(this.gl.enableVertexAttribArray(r.color),this.gl.vertexAttribPointer(r.color,4,this.gl.FLOAT,!1,t,28)),r.texIndex!==-1&&(this.gl.enableVertexAttribArray(r.texIndex),this.gl.vertexAttribPointer(r.texIndex,1,this.gl.FLOAT,!1,t,44)),this.texture){this.texture.bind(0);const u=this.shader.getUniformLocation("uTexture");u!==null&&this.gl.uniform1i(u,0)}const i=this.shader.getUniformLocation("uTileSize");i!==null&&this.gl.uniform2f(i,this.tileSize.width,this.tileSize.height);const s=this.shader.getUniformLocation("uCamera");s!==null&&this.gl.uniform3f(s,e.x,e.y,e.zoom);const o=this.shader.getUniformLocation("uZScale");o!==null&&this.gl.uniform1f(o,this.zScale);const n=this.shader.getUniformLocation("uResolution");n!==null&&this.gl.uniform2f(n,this.resolution.width,this.resolution.height);const a=this.shader.getUniformLocation("uRotation");a!==null&&this.gl.uniform1f(a,0);const c=this.shader.getUniformLocation("uQuadSize");c!==null&&this.gl.uniform2f(c,1,1);const x=this.quads.length*this.verticesPerQuad;this.gl.drawArrays(this.gl.TRIANGLES,0,x),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}}dispose(){this.vertexBuffer&&(this.gl.deleteBuffer(this.vertexBuffer),this.vertexBuffer=null)}}class F{static identity(){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}static translation(e,t,r=0){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,e,t,r,1])}static scale(e,t,r=1){return new Float32Array([e,0,0,0,0,t,0,0,0,0,r,0,0,0,0,1])}static multiply(e,t){const r=new Float32Array(16);for(let i=0;i<4;i++)for(let s=0;s<4;s++){let o=0;for(let n=0;n<4;n++)o+=e[n*4+s]*t[i*4+n];r[i*4+s]=o}return r}static createViewMatrix(e,t,r){const i=F.translation(-e,-t,0),s=F.scale(r,r,1);return F.multiply(i,s)}}class le{constructor(e=0,t=0,r=1){this._viewMatrix=null,this._viewMatrixDirty=!0,this._x=e,this._y=t,this._zoom=r}get x(){return this._x}set x(e){this._x=e,this._viewMatrixDirty=!0}get y(){return this._y}set y(e){this._y=e,this._viewMatrixDirty=!0}get zoom(){return this._zoom}set zoom(e){this._zoom=Math.max(.001,e),this._viewMatrixDirty=!0}setPosition(e,t){this._x=e,this._y=t,this._viewMatrixDirty=!0}move(e,t){this._x+=e,this._y+=t,this._viewMatrixDirty=!0}zoomBy(e){this._zoom=Math.max(.001,this._zoom*e),this._viewMatrixDirty=!0}reset(){this._x=0,this._y=0,this._zoom=1,this._viewMatrixDirty=!0}getViewMatrix(){return(this._viewMatrixDirty||this._viewMatrix===null)&&(this._viewMatrix=F.createViewMatrix(this._x,this._y,this._zoom),this._viewMatrixDirty=!1),this._viewMatrix}screenToWorld(e,t,r,i){const s=e-r/2,o=t-i/2,n=s/this._zoom+this._x,a=o/this._zoom+this._y;return{x:n,y:a}}worldToScreen(e,t,r,i){const s=(e-this._x)*this._zoom,o=(t-this._y)*this._zoom,n=s+r/2,a=o+i/2;return{x:n,y:a}}}class ue{constructor(e=64,t=32,r=1){this.tileWidth=e,this.tileHeight=t,this.zScale=r}}class j{constructor(e="",t=1e4){this.baseUrl=e||this.getCurrentOrigin(),this.defaultTimeout=t}getCurrentOrigin(){return typeof window<"u"?window.location.origin:"http://localhost"}resolvePath(e){try{return e.startsWith("http://")||e.startsWith("https://")?e:e.startsWith("//")?window.location.protocol+e:e.startsWith("/")?this.baseUrl+e:`${this.baseUrl}/${e}`}catch{return e}}async load(e,t){const r=this.resolvePath(e);try{const i={credentials:t?.credentials||"same-origin"};t?.headers&&(i.headers=t.headers);const s=new AbortController,o=setTimeout(()=>s.abort(),this.defaultTimeout);i.signal=s.signal;const n=await fetch(r,i);if(clearTimeout(o),!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText} for URL: ${r}`);return await n.text()}catch(i){throw i instanceof Error?i.name==="AbortError"?new Error(`Request timeout after ${this.defaultTimeout}ms for URL: ${r}`):new Error(`Failed to load resource from ${r}: ${i.message}`):new Error(`Failed to load resource from ${r}: Unknown error`)}}async loadMultiple(e,t){const r=e.map(async i=>{try{return{data:await this.load(i,t),path:i,success:!0}}catch(s){return{data:"",path:i,success:!1,error:s instanceof Error?s.message:String(s)}}});return Promise.all(r)}canLoad(e){const t=[/^https?:\/\//i,/^\/\//,/^\//,/^\.\.?\//],r=/\.[a-z0-9]+$/i.test(e);return t.some(i=>i.test(e))||r}setBaseUrl(e){this.baseUrl=e}getBaseUrl(){return this.baseUrl}setTimeout(e){this.defaultTimeout=e}}const de=Object.freeze(Object.defineProperty({__proto__:null,BrowserResourceLoader:j},Symbol.toStringTag,{value:"Module"}));class K{constructor(e=process.cwd()){this.baseDir=e}resolvePath(e){return L.isAbsolute(e)?L.normalize(e):L.normalize(L.join(this.baseDir,e))}async load(e,t){const r=this.resolvePath(e),i=t?.encoding||"utf-8";try{return await D.readFile(r,i)}catch(s){if(s instanceof Error){const o=s.code;throw o==="ENOENT"?new Error(`File not found: ${r} (resolved from: ${e})`):o==="EACCES"?new Error(`Permission denied reading file: ${r}`):o==="EISDIR"?new Error(`Path is a directory, not a file: ${r}`):new Error(`Failed to load resource from ${r}: ${s.message}`)}throw new Error(`Failed to load resource from ${r}: Unknown error`)}}async loadMultiple(e,t){const r=e.map(async i=>{try{return{data:await this.load(i,t),path:i,success:!0}}catch(s){return{data:"",path:i,success:!1,error:s instanceof Error?s.message:String(s)}}});return Promise.all(r)}canLoad(e){return[/^\//,/^[a-zA-Z]:/,/^\.\.?\//,/^[^/\\]+\//].some(r=>r.test(e))}async exists(e){const t=this.resolvePath(e);try{return await D.access(t,D.constants.F_OK),!0}catch{return!1}}async getStats(e){const t=this.resolvePath(e);return D.stat(t)}setBaseDir(e){this.baseDir=e}getBaseDir(){return this.baseDir}async listDirectory(e,t=!1){const r=this.resolvePath(e),i=await D.readdir(r,{withFileTypes:!0}),s=[];for(const o of i){const n=L.join(r,o.name);if(o.isDirectory()&&t){const a=await this.listDirectory(n,!0);s.push(...a)}else o.isFile()&&s.push(n)}return s}}const fe=Object.freeze(Object.defineProperty({__proto__:null,NodeResourceLoader:K},Symbol.toStringTag,{value:"Module"}));var S=(h=>(h.BROWSER="browser",h.NODE="node",h.UNKNOWN="unknown",h))(S||{});class U{static detectEnvironment(){return typeof window<"u"&&typeof window.document<"u"&&typeof fetch<"u"?"browser":typeof process<"u"&&process.versions!=null&&process.versions.node!=null?"node":"unknown"}static isBrowser(){return this.detectEnvironment()==="browser"}static isNode(){return this.detectEnvironment()==="node"}static async create(e){const t=e?.forceEnvironment||this.detectEnvironment();switch(t){case"browser":return await this.createBrowserLoader(e);case"node":return await this.createNodeLoader(e);case"unknown":throw new Error("Unsupported environment: Unable to determine runtime environment. Please specify forceEnvironment in options.");default:throw new Error(`Unsupported environment: ${t}`)}}static async createBrowserLoader(e){const{BrowserResourceLoader:t}=await Promise.resolve().then(()=>de);return new t(e?.baseUrl,e?.timeout)}static async createNodeLoader(e){const{NodeResourceLoader:t}=await Promise.resolve().then(()=>fe);return new t(e?.baseDir)}static async createWithFallback(e,t){try{return t={...t,forceEnvironment:e},await this.create(t)}catch{return await this.create({...t,forceEnvironment:void 0})}}}async function Z(h){return await U.create(h)}const ge=Object.freeze(Object.defineProperty({__proto__:null,Environment:S,ResourceLoaderFactory:U,createResourceLoader:Z},Symbol.toStringTag,{value:"Module"}));class xe{constructor(e=!0){this.cache=new Map,this.enabled=e}get(e){if(this.enabled)return this.cache.get(e)}set(e,t){this.enabled&&this.cache.set(e,t)}has(e){return this.enabled?this.cache.has(e):!1}clear(){this.cache.clear()}size(){return this.cache.size}enable(){this.enabled=!0}disable(){this.enabled=!1}}class J{constructor(e,t){this.loader=e,this.concurrency=t?.concurrency??10,this.cache=new xe(t?.cache??!0)}async load(e,t){const r=this.cache.get(e);if(r!==void 0)return r;const i=await this.loader.load(e,t);return this.cache.set(e,i),i}async loadBatch(e,t){const r=new Map,i=new Map;for(let s=0;s<e.length;s+=this.concurrency){const o=e.slice(s,s+this.concurrency),n=await this.loader.loadMultiple(o,t);for(const a of n)a.success?(r.set(a.path,a.data),this.cache.set(a.path,a.data)):i.set(a.path,a.error||"Unknown error")}return{succeeded:r,failed:i,total:e.length,successCount:r.size,failureCount:i.size}}async loadShader(e,t,r){const[i,s]=await Promise.all([this.load(e,r),this.load(t,r)]);return{vertex:i,fragment:s}}async loadShaders(e,t){return await Promise.all(e.map(async i=>{const s=await this.loadShader(i.vertex,i.fragment,t);return{name:i.name,...s}}))}async loadFromManifest(e,t){const r=await this.load(e,t),i=JSON.parse(r);return this.loadBatch(i.resources,t)}async preload(e,t){await this.loadBatch(e,t)}isCached(e){return this.cache.has(e)}getCached(e){return this.cache.get(e)}clearCache(){this.cache.clear()}getCacheSize(){return this.cache.size()}enableCache(){this.cache.enable()}disableCache(){this.cache.disable()}setConcurrency(e){this.concurrency=Math.max(1,e)}getLoader(){return this.loader}}async function ee(h){const{ResourceLoaderFactory:e}=await Promise.resolve().then(()=>ge),t=await e.create({baseUrl:h?.baseUrl,baseDir:h?.baseDir,timeout:h?.timeout});return new J(t,h)}const M={width:800,height:600},z={quad:{vertices:new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,.5,.5,0,1,1,-.5,.5,0,0,1,-.5,-.5,0,0,0]),stride:20}},$={size:256},I={shaders:[{name:"basic",vertex:"resources/shaders/basic.vert",fragment:"resources/shaders/basic.frag"},{name:"glow",vertex:"resources/shaders/glow.vert",fragment:"resources/shaders/glow.frag"}],resources:["resources/shaders/basic.vert","resources/shaders/basic.frag","resources/shaders/glow.vert","resources/shaders/glow.frag"]};async function we(){console.log("🩸 Bloody Engine - Resource Loader Demo"),console.log(`==========================================
10
+ `);const h=U.detectEnvironment();if(console.log(`✓ Environment detected: ${h}`),h!==S.BROWSER){console.warn("⚠ This demo is designed for browser environment");return}console.log(`
11
11
  1. Creating Resource Pipeline...`);const e=await ee({concurrency:5,cache:!0,timeout:1e4,baseUrl:window.location.origin});console.log("✓ Resource pipeline created"),console.log(" - Concurrency: 5"),console.log(" - Caching: enabled"),console.log(`
12
- 2. Batch Loading Resources...`),console.log(`Loading ${z.resources.length} resources...`);const t=await e.loadBatch(z.resources);if(console.log("✓ Batch loading complete"),console.log(` - Succeeded: ${t.successCount}`),console.log(` - Failed: ${t.failureCount}`),t.failureCount>0){console.log(`
13
- ❌ Failed resources:`);for(const[x,L]of t.failed)console.log(` - ${x}: ${L}`);console.log(`
12
+ 2. Batch Loading Resources...`),console.log(`Loading ${I.resources.length} resources...`);const t=await e.loadBatch(I.resources);if(console.log("✓ Batch loading complete"),console.log(` - Succeeded: ${t.successCount}`),console.log(` - Failed: ${t.failureCount}`),t.failureCount>0){console.log(`
13
+ ❌ Failed resources:`);for(const[v,P]of t.failed)console.log(` - ${v}: ${P}`);console.log(`
14
14
  ⚠️ Falling back to inline shaders...`)}console.log(`
15
- 3. Loading Shaders...`);const r=await e.loadShaders(z.shaders);console.log(`✓ Loaded ${r.length} shaders:`);for(const x of r)console.log(` - ${x.name}:`),console.log(` Vertex: ${x.vertex.length} chars`),console.log(` Fragment: ${x.fragment.length} chars`);console.log(`
16
- 4. Testing Cache...`);const s=e.getCacheSize();console.log(`✓ Cache contains ${s} resources`);for(const x of z.shaders){const L=e.isCached(x.vertex),Y=e.isCached(x.fragment);console.log(` - ${x.name}:`),console.log(` Vertex cached: ${L}`),console.log(` Fragment cached: ${Y}`)}console.log(`
17
- 5. Initializing Graphics Device...`);const i=new H(U.width,U.height),o=i.getGLContext();console.log("✓ Graphics device initialized"),console.log(` - Resolution: ${U.width}x${U.height}`),console.log(`
18
- 6. Creating Shader from Loaded Source...`);let n=r.find(x=>x.name==="glow");(!n||!n.vertex||!n.fragment)&&(console.warn("⚠️ Glow shader not loaded or empty, using inline fallback"),n={name:"glow",vertex:`attribute vec3 aPosition;
15
+ 3. Loading Shaders...`);const r=await e.loadShaders(I.shaders);console.log(`✓ Loaded ${r.length} shaders:`);for(const v of r)console.log(` - ${v.name}:`),console.log(` Vertex: ${v.vertex.length} chars`),console.log(` Fragment: ${v.fragment.length} chars`);console.log(`
16
+ 4. Testing Cache...`);const i=e.getCacheSize();console.log(`✓ Cache contains ${i} resources`);for(const v of I.shaders){const P=e.isCached(v.vertex),q=e.isCached(v.fragment);console.log(` - ${v.name}:`),console.log(` Vertex cached: ${P}`),console.log(` Fragment cached: ${q}`)}console.log(`
17
+ 5. Initializing Graphics Device...`);const s=new X(M.width,M.height),o=s.getGLContext();console.log("✓ Graphics device initialized"),console.log(` - Resolution: ${M.width}x${M.height}`),console.log(`
18
+ 6. Creating Shader from Loaded Source...`);let n=r.find(v=>v.name==="glow");(!n||!n.vertex||!n.fragment)&&(console.warn("⚠️ Glow shader not loaded or empty, using inline fallback"),n={name:"glow",vertex:`attribute vec3 aPosition;
19
19
  attribute vec2 aTexCoord;
20
20
 
21
21
  varying vec2 vTexCoord;
@@ -42,15 +42,15 @@ void main() {
42
42
  glow = max(0.5, glow);
43
43
  vec3 glowColor = texColor.rgb * uColor * glow * uGlowIntensity;
44
44
  gl_FragColor = vec4(glowColor, texColor.a);
45
- }`});const c=i.createShader(n.vertex,n.fragment);console.log("✓ Shader compiled from loaded source code"),console.log(" - Vertex shader: compiled"),console.log(" - Fragment shader: compiled"),console.log(" - Program: linked"),console.log(`
46
- 7. Creating Texture...`);const h=R.createGradient(o,$.size,$.size);console.log("✓ Gradient texture created"),console.log(` - Size: ${$.size}x${$.size}`),console.log(`
47
- 8. Creating Geometry Buffers...`);const{VertexBuffer:m}=await Promise.resolve().then(()=>ie),u=new m(o,M.quad.vertices,M.quad.stride);console.log("✓ Quad buffer created"),console.log(` - Vertices: ${u.getVertexCount()}`),console.log(`
48
- 9. Setting up Rendering...`),c.use();const f=c.getAttributeLocation("aPosition"),g=c.getAttributeLocation("aTexCoord"),E=c.getUniformLocation("uTexture"),v=c.getUniformLocation("uMatrix"),b=c.getUniformLocation("uColor"),_=c.getUniformLocation("uGlowIntensity");u.bind(),o.enableVertexAttribArray(f),o.vertexAttribPointer(f,3,o.FLOAT,!1,M.quad.stride,0),o.enableVertexAttribArray(g),o.vertexAttribPointer(g,2,o.FLOAT,!1,M.quad.stride,12),console.log("✓ Vertex attributes configured"),h.bind(0),o.uniform1i(E,0),console.log("✓ Texture bound to unit 0");const d=i.getRenderingContext().canvas;d&&(d.style.display="block",d.style.margin="0 auto",d.style.border="2px solid #333",d.style.backgroundColor="#1a1a1a"),document.body.style.margin="0",document.body.style.padding="20px",document.body.style.backgroundColor="#0a0a0a",document.body.style.fontFamily="monospace",document.body.style.color="#aaa";const w=document.createElement("h1");w.textContent="🩸 Resource Loader Demo",w.style.textAlign="center",w.style.color="#fff",d&&d.parentNode?d.parentNode.insertBefore(w,d):document.body.insertBefore(w,document.body.firstChild);const y=document.createElement("div");y.style.textAlign="center",y.style.marginTop="10px",y.style.fontSize="12px",y.innerHTML=`
49
- <div>Environment: <strong>${a}</strong></div>
45
+ }`});const a=s.createShader(n.vertex,n.fragment);console.log("✓ Shader compiled from loaded source code"),console.log(" - Vertex shader: compiled"),console.log(" - Fragment shader: compiled"),console.log(" - Program: linked"),console.log(`
46
+ 7. Creating Texture...`);const c=T.createGradient(o,$.size,$.size);console.log("✓ Gradient texture created"),console.log(` - Size: ${$.size}x${$.size}`),console.log(`
47
+ 8. Creating Geometry Buffers...`);const{VertexBuffer:x}=await Promise.resolve().then(()=>ne),u=new x(o,z.quad.vertices,z.quad.stride);console.log("✓ Quad buffer created"),console.log(` - Vertices: ${u.getVertexCount()}`),console.log(`
48
+ 9. Setting up Rendering...`),a.use();const g=a.getAttributeLocation("aPosition"),f=a.getAttributeLocation("aTexCoord"),A=a.getUniformLocation("uTexture"),w=a.getUniformLocation("uMatrix"),m=a.getUniformLocation("uColor"),R=a.getUniformLocation("uGlowIntensity");u.bind(),o.enableVertexAttribArray(g),o.vertexAttribPointer(g,3,o.FLOAT,!1,z.quad.stride,0),o.enableVertexAttribArray(f),o.vertexAttribPointer(f,2,o.FLOAT,!1,z.quad.stride,12),console.log("✓ Vertex attributes configured"),c.bind(0),o.uniform1i(A,0),console.log("✓ Texture bound to unit 0");const d=s.getRenderingContext().canvas;d&&(d.style.display="block",d.style.margin="0 auto",d.style.border="2px solid #333",d.style.backgroundColor="#1a1a1a"),document.body.style.margin="0",document.body.style.padding="20px",document.body.style.backgroundColor="#0a0a0a",document.body.style.fontFamily="monospace",document.body.style.color="#aaa";const b=document.createElement("h1");b.textContent="🩸 Resource Loader Demo",b.style.textAlign="center",b.style.color="#fff",d&&d.parentNode?d.parentNode.insertBefore(b,d):document.body.insertBefore(b,document.body.firstChild);const y=document.createElement("div");y.style.textAlign="center",y.style.marginTop="10px",y.style.fontSize="12px",y.innerHTML=`
49
+ <div>Environment: <strong>${h}</strong></div>
50
50
  <div>Shaders loaded: <strong>${r.length}</strong></div>
51
- <div>Cached resources: <strong>${s}</strong></div>
52
- `,document.body.appendChild(y);let D=0;const I=Date.now();function N(){const x=Date.now(),L=(x-I)/1e3;i.clear({r:.1,g:.1,b:.1,a:1});const Y=[{x:-.3,y:.3,color:[1,.2,.2],glow:1.5},{x:.3,y:.3,color:[.2,1,.2],glow:1.8},{x:-.3,y:-.3,color:[.2,.5,1],glow:2},{x:.3,y:-.3,color:[1,1,.2],glow:1.6}];for(const B of Y){const G=fe();if(ge(G,B.x,B.y,0),xe(G,.4,.4,1),v&&o.uniformMatrix4fv(v,!1,G),b&&o.uniform3f(b,B.color[0],B.color[1],B.color[2]),_){const ve=B.glow+Math.sin(L*2)*.3;o.uniform1f(_,ve)}o.drawArrays(o.TRIANGLES,0,u.getVertexCount())}i.present(),D++;const te=(x-I)/1e3,me=D/te;y.innerHTML=`
53
- <div>FPS: <strong>${me.toFixed(1)}</strong> | Frame: <strong>${D}</strong> | Elapsed: <strong>${te.toFixed(2)}s</strong></div>
54
- <div>Environment: <strong>${a}</strong> | Shaders loaded: <strong>${r.length}</strong> | Cached: <strong>${s}</strong></div>
55
- `,requestAnimationFrame(N)}console.log(`
56
- ✓ Demo started! Rendering animation...`),N()}function fe(){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}function ge(a,e,t,r){a[12]+=e,a[13]+=t,a[14]+=r}function xe(a,e,t,r){a[0]*=e,a[5]*=t,a[10]*=r}l.BatchRenderer=oe,l.BrowserRenderingContext=O,l.BrowserResourceLoader=Q,l.Camera=ae,l.Environment=P,l.GraphicsDevice=H,l.IndexBuffer=j,l.Matrix4=A,l.NodeRenderingContext=V,l.NodeResourceLoader=K,l.RenderingContextFactory=X,l.ResourceLoaderFactory=S,l.ResourcePipeline=Z,l.Shader=k,l.SpriteBatchRenderer=ne,l.Texture=R,l.VertexBuffer=W,l.createResourceLoader=J,l.createResourcePipeline=ee,l.runBrowserResourceLoaderDemo=de,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
51
+ <div>Cached resources: <strong>${i}</strong></div>
52
+ `,document.body.appendChild(y);let B=0;const p=Date.now();function O(){const v=Date.now(),P=(v-p)/1e3;s.clear({r:.1,g:.1,b:.1,a:1});const q=[{x:-.3,y:.3,color:[1,.2,.2],glow:1.5},{x:.3,y:.3,color:[.2,1,.2],glow:1.8},{x:-.3,y:-.3,color:[.2,.5,1],glow:2},{x:.3,y:-.3,color:[1,1,.2],glow:1.6}];for(const C of q){const N=me();if(ve(N,C.x,C.y,0),be(N,.4,.4,1),w&&o.uniformMatrix4fv(w,!1,N),m&&o.uniform3f(m,C.color[0],C.color[1],C.color[2]),R){const Ae=C.glow+Math.sin(P*2)*.3;o.uniform1f(R,Ae)}o.drawArrays(o.TRIANGLES,0,u.getVertexCount())}s.present(),B++;const te=(v-p)/1e3,ye=B/te;y.innerHTML=`
53
+ <div>FPS: <strong>${ye.toFixed(1)}</strong> | Frame: <strong>${B}</strong> | Elapsed: <strong>${te.toFixed(2)}s</strong></div>
54
+ <div>Environment: <strong>${h}</strong> | Shaders loaded: <strong>${r.length}</strong> | Cached: <strong>${i}</strong></div>
55
+ `,requestAnimationFrame(O)}console.log(`
56
+ ✓ Demo started! Rendering animation...`),O()}function me(){return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}function ve(h,e,t,r){h[12]+=e,h[13]+=t,h[14]+=r}function be(h,e,t,r){h[0]*=e,h[5]*=t,h[10]*=r}l.BatchRenderer=ae,l.BrowserRenderingContext=V,l.BrowserResourceLoader=j,l.Camera=le,l.Environment=S,l.GPUBasedSpriteBatchRenderer=ce,l.GraphicsDevice=X,l.IndexBuffer=H,l.Matrix4=F,l.NodeRenderingContext=Y,l.NodeResourceLoader=K,l.ProjectionConfig=ue,l.RenderingContextFactory=W,l.ResourceLoaderFactory=U,l.ResourcePipeline=J,l.SDLWindow=oe,l.Shader=Q,l.SpriteBatchRenderer=he,l.Texture=T,l.VertexBuffer=k,l.createResourceLoader=Z,l.createResourcePipeline=ee,l.runBrowserResourceLoaderDemo=we,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,31 @@
1
+ import { RenderingContext, RenderingContextOptions } from '../../rendering/rendering-context';
2
+ /**
3
+ * Browser-based WebGL rendering context implementation
4
+ * Manages rendering to an HTML canvas element
5
+ */
6
+ export declare class BrowserRenderingContext implements RenderingContext {
7
+ glContext: WebGLRenderingContext;
8
+ width: number;
9
+ height: number;
10
+ isBrowser: boolean;
11
+ private canvas;
12
+ constructor(options: RenderingContextOptions);
13
+ resize(width: number, height: number): void;
14
+ getViewport(): {
15
+ width: number;
16
+ height: number;
17
+ };
18
+ clear(color?: {
19
+ r: number;
20
+ g: number;
21
+ b: number;
22
+ a: number;
23
+ }): void;
24
+ present(): void;
25
+ dispose(): void;
26
+ /**
27
+ * Get the underlying canvas element (browser-specific)
28
+ */
29
+ getCanvas(): HTMLCanvasElement;
30
+ }
31
+ //# sourceMappingURL=browser-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-context.d.ts","sourceRoot":"","sources":["../../../../src/platforms/browser/browser-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,mCAAmC,CAAC;AAE3C;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,gBAAgB;IAC9D,SAAS,EAAE,qBAAqB,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAQ;IAE1B,OAAO,CAAC,MAAM,CAAoB;gBAEtB,OAAO,EAAE,uBAAuB;IA0B5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ3C,WAAW,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAIhD,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IASnE,OAAO,IAAI,IAAI;IAIf,OAAO,IAAI,IAAI;IAOf;;OAEG;IACH,SAAS,IAAI,iBAAiB;CAG/B"}
@@ -0,0 +1,67 @@
1
+ import { IResourceLoader, ResourceLoadOptions, ResourceLoadResult } from '../../core/resource-loader';
2
+ /**
3
+ * Resource loader implementation for browser environments
4
+ * Uses the Fetch API to load resources from URLs
5
+ */
6
+ export declare class BrowserResourceLoader implements IResourceLoader {
7
+ /**
8
+ * Base URL for resolving relative paths
9
+ */
10
+ private baseUrl;
11
+ /**
12
+ * Default request timeout in milliseconds
13
+ */
14
+ private defaultTimeout;
15
+ /**
16
+ * Create a new browser resource loader
17
+ * @param baseUrl Optional base URL for resolving relative paths (defaults to current origin)
18
+ * @param timeout Default timeout for requests in milliseconds (default: 10000)
19
+ */
20
+ constructor(baseUrl?: string, timeout?: number);
21
+ /**
22
+ * Get the current origin (protocol + host + port)
23
+ */
24
+ private getCurrentOrigin;
25
+ /**
26
+ * Resolve a relative path against the base URL
27
+ * @param path Relative or absolute path
28
+ * @returns Resolved absolute URL
29
+ */
30
+ private resolvePath;
31
+ /**
32
+ * Load a single resource from a URL
33
+ * @param path URL or relative path to the resource
34
+ * @param options Optional loading configuration
35
+ * @returns Promise resolving to the resource content
36
+ */
37
+ load(path: string, options?: ResourceLoadOptions): Promise<string>;
38
+ /**
39
+ * Load multiple resources in parallel
40
+ * @param paths Array of URLs or paths
41
+ * @param options Optional loading configuration
42
+ * @returns Promise resolving to array of load results
43
+ */
44
+ loadMultiple(paths: string[], options?: ResourceLoadOptions): Promise<ResourceLoadResult[]>;
45
+ /**
46
+ * Check if the path is valid for loading in the browser
47
+ * @param path URL or path to check
48
+ * @returns true if the path can be loaded
49
+ */
50
+ canLoad(path: string): boolean;
51
+ /**
52
+ * Set a new base URL for resolving relative paths
53
+ * @param baseUrl New base URL
54
+ */
55
+ setBaseUrl(baseUrl: string): void;
56
+ /**
57
+ * Get the current base URL
58
+ * @returns Current base URL
59
+ */
60
+ getBaseUrl(): string;
61
+ /**
62
+ * Set the default request timeout
63
+ * @param timeout Timeout in milliseconds
64
+ */
65
+ setTimeout(timeout: number): void;
66
+ }
67
+ //# sourceMappingURL=browser-resource-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-resource-loader.d.ts","sourceRoot":"","sources":["../../../../src/platforms/browser/browser-resource-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAEpC;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,eAAe;IAC3D;;OAEG;IACH,OAAO,CAAC,OAAO,CAAS;IAExB;;OAEG;IACH,OAAO,CAAC,cAAc,CAAS;IAE/B;;;;OAIG;gBACS,OAAO,GAAE,MAAW,EAAE,OAAO,GAAE,MAAc;IAKzD;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAyBnB;;;;;OAKG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CxE;;;;;OAKG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAsBhC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAe9B;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC;;;OAGG;IACH,UAAU,IAAI,MAAM;IAIpB;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAGlC"}
@@ -0,0 +1,31 @@
1
+ import { RenderingContext, RenderingContextOptions } from '../../rendering/rendering-context';
2
+ /**
3
+ * Node.js-based WebGL rendering context implementation
4
+ * Uses headless-gl (node-gl) for server-side rendering
5
+ */
6
+ export declare class NodeRenderingContext implements RenderingContext {
7
+ glContext: WebGLRenderingContext;
8
+ width: number;
9
+ height: number;
10
+ isBrowser: boolean;
11
+ constructor(options: RenderingContextOptions);
12
+ resize(width: number, height: number): void;
13
+ getViewport(): {
14
+ width: number;
15
+ height: number;
16
+ };
17
+ clear(color?: {
18
+ r: number;
19
+ g: number;
20
+ b: number;
21
+ a: number;
22
+ }): void;
23
+ present(): void;
24
+ dispose(): void;
25
+ /**
26
+ * Read the current framebuffer contents as RGBA pixel data
27
+ * Used for capturing frames for display or saving
28
+ */
29
+ readPixels(): Uint8Array;
30
+ }
31
+ //# sourceMappingURL=node-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-context.d.ts","sourceRoot":"","sources":["../../../../src/platforms/node/node-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,mCAAmC,CAAC;AAE3C;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,SAAS,EAAE,qBAAqB,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAS;gBAEf,OAAO,EAAE,uBAAuB;IAiB5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAU3C,WAAW,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAIhD,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IASnE,OAAO,IAAI,IAAI;IAKf,OAAO,IAAI,IAAI;IAOf;;;OAGG;IACH,UAAU,IAAI,UAAU;CAazB"}
@@ -0,0 +1,73 @@
1
+ import { Stats } from 'fs';
2
+ import { IResourceLoader, ResourceLoadOptions, ResourceLoadResult } from '../../core/resource-loader';
3
+ /**
4
+ * Resource loader implementation for Node.js environments
5
+ * Uses fs.promises to load resources from the file system
6
+ */
7
+ export declare class NodeResourceLoader implements IResourceLoader {
8
+ /**
9
+ * Base directory for resolving relative paths
10
+ */
11
+ private baseDir;
12
+ /**
13
+ * Create a new Node.js resource loader
14
+ * @param baseDir Optional base directory for resolving relative paths (defaults to current working directory)
15
+ */
16
+ constructor(baseDir?: string);
17
+ /**
18
+ * Resolve a relative path against the base directory
19
+ * @param filePath Relative or absolute file path
20
+ * @returns Resolved absolute file path
21
+ */
22
+ private resolvePath;
23
+ /**
24
+ * Load a single resource from a file
25
+ * @param filePath File path (relative or absolute)
26
+ * @param options Optional loading configuration
27
+ * @returns Promise resolving to the file content
28
+ */
29
+ load(filePath: string, options?: ResourceLoadOptions): Promise<string>;
30
+ /**
31
+ * Load multiple resources in parallel
32
+ * @param filePaths Array of file paths
33
+ * @param options Optional loading configuration
34
+ * @returns Promise resolving to array of load results
35
+ */
36
+ loadMultiple(filePaths: string[], options?: ResourceLoadOptions): Promise<ResourceLoadResult[]>;
37
+ /**
38
+ * Check if the path is valid for loading in Node.js
39
+ * @param filePath File path to check
40
+ * @returns true if the path can be loaded
41
+ */
42
+ canLoad(filePath: string): boolean;
43
+ /**
44
+ * Check if a file exists without loading it
45
+ * @param filePath File path to check
46
+ * @returns Promise resolving to true if file exists
47
+ */
48
+ exists(filePath: string): Promise<boolean>;
49
+ /**
50
+ * Get file statistics (size, modification time, etc.)
51
+ * @param filePath File path to check
52
+ * @returns Promise resolving to file stats
53
+ */
54
+ getStats(filePath: string): Promise<Stats>;
55
+ /**
56
+ * Set a new base directory for resolving relative paths
57
+ * @param baseDir New base directory
58
+ */
59
+ setBaseDir(baseDir: string): void;
60
+ /**
61
+ * Get the current base directory
62
+ * @returns Current base directory
63
+ */
64
+ getBaseDir(): string;
65
+ /**
66
+ * List all files in a directory
67
+ * @param dirPath Directory path to list
68
+ * @param recursive Whether to recursively list subdirectories (default: false)
69
+ * @returns Promise resolving to array of file paths
70
+ */
71
+ listDirectory(dirPath: string, recursive?: boolean): Promise<string[]>;
72
+ }
73
+ //# sourceMappingURL=node-resource-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-resource-loader.d.ts","sourceRoot":"","sources":["../../../../src/platforms/node/node-resource-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAEpC;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD;;OAEG;IACH,OAAO,CAAC,OAAO,CAAS;IAExB;;;OAGG;gBACS,OAAO,GAAE,MAAsB;IAI3C;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAUnB;;;;;OAKG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAuC5E;;;;;OAKG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAsBhC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAYlC;;;;OAIG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUhD;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAKhD;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC;;;OAGG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;;OAKG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,MAAM,EAAE,CAAC;CAkBrB"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SDL Window wrapper for displaying rendered content
3
+ * Handles window creation, event polling, and surface updates
4
+ */
5
+ export declare class SDLWindow {
6
+ private window;
7
+ private width;
8
+ private height;
9
+ private title;
10
+ private closed;
11
+ constructor(width: number, height: number, title?: string);
12
+ /**
13
+ * Get window dimensions
14
+ */
15
+ getDimensions(): {
16
+ width: number;
17
+ height: number;
18
+ };
19
+ /**
20
+ * Display pixel data in the window
21
+ * @param pixels Uint8Array of RGBA pixel data
22
+ */
23
+ updatePixels(pixels: Uint8Array): void;
24
+ /**
25
+ * Register an event handler
26
+ */
27
+ on(eventName: string, handler: Function): void;
28
+ /**
29
+ * Check if window is still open
30
+ */
31
+ isOpen(): boolean;
32
+ /**
33
+ * Cleanup and close window
34
+ */
35
+ cleanup(): void;
36
+ /**
37
+ * Destroy the window (alias for cleanup)
38
+ */
39
+ destroy(): void;
40
+ }
41
+ //# sourceMappingURL=sdl-window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdl-window.d.ts","sourceRoot":"","sources":["../../../../src/platforms/node/sdl-window.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAkB;gBAEpB,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAwB;IA6B1E;;OAEG;IACH,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAIlD;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAkBtC;;OAEG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,IAAI;IAkB9C;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,OAAO,IAAI,IAAI;IAcf;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for 2.5D Isometric Projection Mathematics
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=projection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.test.d.ts","sourceRoot":"","sources":["../../src/projection.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,25 @@
1
+ export { GraphicsDevice } from './core/grahpic-device';
2
+ export type { RenderingContext, RenderingContextOptions, } from './rendering/rendering-context';
3
+ export { BrowserRenderingContext } from './platforms/browser/browser-context';
4
+ export { NodeRenderingContext } from './platforms/node/node-context';
5
+ export { RenderingContextFactory } from './rendering/rendering-context-factory';
6
+ export { SDLWindow } from './platforms/node/sdl-window';
7
+ export { Shader } from './core/shader';
8
+ export { Texture } from './core/texture';
9
+ export { VertexBuffer, IndexBuffer } from './core/buffer';
10
+ export { BatchRenderer, SpriteBatchRenderer, GPUBasedSpriteBatchRenderer } from './rendering/batch-renderer';
11
+ export type { QuadInstance, SpriteQuadInstance } from './rendering/batch-renderer';
12
+ export type { SpriteVertex } from './rendering/vertex';
13
+ export { Camera, Matrix4 } from './rendering/camera';
14
+ export { ProjectionConfig } from './rendering/projection';
15
+ export type { GridCoord, ScreenCoord, FractionalGridCoord } from './rendering/projection';
16
+ export type { IResourceLoader, ResourceLoadResult, ResourceLoadOptions, BatchLoadResult, } from './core/resource-loader';
17
+ export { BrowserResourceLoader, } from './platforms/browser/browser-resource-loader';
18
+ export { NodeResourceLoader } from './platforms/node/node-resource-loader';
19
+ export { ResourceLoaderFactory, Environment, createResourceLoader, } from './core/resource-loader-factory';
20
+ export type { ResourceLoaderFactoryOptions } from './core/resource-loader-factory';
21
+ export { ResourcePipeline, createResourcePipeline, } from './core/resource-pipeline';
22
+ export type { ShaderSource, NamedShaderSource, ResourcePipelineOptions, } from './core/resource-pipeline';
23
+ export type { VisualizationEntity } from './scene/scene';
24
+ export { runBrowserResourceLoaderDemo } from './examples/resource-loader-demo';
25
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/public-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,YAAY,EACV,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC7G,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGnF,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG1F,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,GACtB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AACxC,YAAY,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EACL,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC"}