From 1faac140debd05663ceee36193fae9f139bcb670 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:59:17 +0200 Subject: [PATCH 01/22] actually use the Camera's matricies and fix mistake with the matrix lookat thingy --- src/gl/gl_renderer.c | 2 ++ src/runner.h | 2 ++ src/vm_builtins.c | 48 +++++++++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 74f5fb43..6d1d7af0 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -707,6 +707,7 @@ static void glEndView(Renderer* renderer) { // camera_apply: swap the active world->clip projection on the current target without touching its viewport. static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { GLRenderer* gl = (GLRenderer*) renderer; + // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); Matrix4f projection = *worldToClip; @@ -714,6 +715,7 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); renderer->previousViewMatrix = projection; + } static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { diff --git a/src/runner.h b/src/runner.h index c6c4796e..efaf6e0b 100644 --- a/src/runner.h +++ b/src/runner.h @@ -159,6 +159,8 @@ typedef struct { // Center derived from camera_set_view_mat; kept so set_view_mat / set_proj_mat (which arrive in either order) can both recompute the top-left viewX/viewY once the size from the proj matrix is known. int32_t viewMatCenterX; int32_t viewMatCenterY; + Matrix4f ViewMatrix; + Matrix4f ProjectionMatrix; } GMLCamera; typedef struct { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index becf67a6..6b8a1d40 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3007,20 +3007,20 @@ static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *a Matrix4f_identity(&matrix); matrix.m[Matrix_getIndex(0, 0)] = xRight; - matrix.m[Matrix_getIndex(0, 1)] = xUp; - matrix.m[Matrix_getIndex(0, 2)] = xLook; + matrix.m[Matrix_getIndex(1, 0)] = xUp; + matrix.m[Matrix_getIndex(2, 0)] = xLook; - matrix.m[Matrix_getIndex(1, 0)] = yRight; + matrix.m[Matrix_getIndex(0, 1)] = yRight; matrix.m[Matrix_getIndex(1, 1)] = yUp; - matrix.m[Matrix_getIndex(1, 2)] = yLook; + matrix.m[Matrix_getIndex(2, 1)] = yLook; - matrix.m[Matrix_getIndex(2, 0)] = zRight; - matrix.m[Matrix_getIndex(2, 1)] = zUp; + matrix.m[Matrix_getIndex(0, 2)] = zRight; + matrix.m[Matrix_getIndex(1, 2)] = zUp; matrix.m[Matrix_getIndex(2, 2)] = zLook; - matrix.m[Matrix_getIndex(3, 0)] = -x; - matrix.m[Matrix_getIndex(3, 1)] = -y; - matrix.m[Matrix_getIndex(3, 2)] = -z; + matrix.m[Matrix_getIndex(0, 3)] = -x; + matrix.m[Matrix_getIndex(1, 3)] = -y; + matrix.m[Matrix_getIndex(2, 3)] = -z; bool toPrevMatrix = argCount == 10; GMLArray *destArray = toPrevMatrix ? args[9].array : nullptr; @@ -3542,9 +3542,24 @@ static RValue builtin_camera_set_view_mat(VMContext* ctx, RValue* args, int32_t camera->viewMatCenterY = (int32_t) lround(-m.m[Matrix_getIndex(3, 1)]); camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; + camera->ViewMatrix = m; return RValue_makeUndefined(); } +static RValue builtin_camera_get_view_mat(VMContext* ctx, RValue* args, int32_t argCount) { + Runner* runner = ctx->runner; + GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); + if (camera == nullptr) return RValue_makeUndefined(); + return RValue_makeArray(matrixToGml(&camera->ViewMatrix)); +} + +static RValue builtin_camera_get_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { + Runner* runner = ctx->runner; + GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); + if (camera == nullptr) return RValue_makeUndefined(); + return RValue_makeArray(matrixToGml(&camera->ProjectionMatrix)); +} + static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { if (2 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; @@ -3559,6 +3574,8 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t if (m11 != 0.0) camera->viewHeight = (int32_t) lround(GMLReal_fabs(2.0 / m11)); camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; + camera->ProjectionMatrix = m; + camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); } @@ -3746,9 +3763,14 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - Matrix4f worldToClip; - Matrix4f_viewProjection(&worldToClip, (float) camera->viewX, (float) camera->viewY, (float) camera->viewWidth, (float) camera->viewHeight, camera->viewAngle); - runner->renderer->vtable->applyProjection(runner->renderer, &worldToClip); + + Matrix4f ViewMatrix = camera->ViewMatrix; + Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + Matrix4f FinalProjection; + Matrix4f_multiply(&FinalProjection, &ProjectionMatrix, &ViewMatrix); + + runner->renderer->vtable->applyProjection(runner->renderer, &FinalProjection); + } return RValue_makeUndefined(); } @@ -15719,7 +15741,9 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "camera_get_view_height", builtin_camera_get_view_height); VM_registerBuiltin(ctx, "camera_set_view_pos", builtin_camera_set_view_pos); VM_registerBuiltin(ctx, "camera_set_view_mat", builtin_camera_set_view_mat); + VM_registerBuiltin(ctx, "camera_get_view_mat", builtin_camera_get_view_mat); VM_registerBuiltin(ctx, "camera_set_proj_mat", builtin_camera_set_proj_mat); + VM_registerBuiltin(ctx, "camera_get_proj_mat", builtin_camera_get_proj_mat); VM_registerBuiltin(ctx, "camera_get_view_target", builtin_camera_get_view_target); VM_registerBuiltin(ctx, "camera_set_view_target", builtin_camera_set_view_target); VM_registerBuiltin(ctx, "camera_get_view_border_x", builtin_camera_get_view_border_x); From ba040918917e5d6a7da72cf45f595f1e21e71941 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:15:02 +0200 Subject: [PATCH 02/22] remove ViewMatCenter --- src/runner.h | 4 +--- src/vm_builtins.c | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/runner.h b/src/runner.h index efaf6e0b..87051266 100644 --- a/src/runner.h +++ b/src/runner.h @@ -156,9 +156,7 @@ typedef struct { int32_t speedY; int32_t objectId; // follow target (object index), -1 = none float viewAngle; - // Center derived from camera_set_view_mat; kept so set_view_mat / set_proj_mat (which arrive in either order) can both recompute the top-left viewX/viewY once the size from the proj matrix is known. - int32_t viewMatCenterX; - int32_t viewMatCenterY; + Matrix4f ViewMatrix; Matrix4f ProjectionMatrix; } GMLCamera; diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 6b8a1d40..f751d522 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3537,11 +3537,6 @@ static RValue builtin_camera_set_view_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - // For an axis-aligned 2D camera the view-matrix translation encodes -(camera center). - camera->viewMatCenterX = (int32_t) lround(-m.m[Matrix_getIndex(3, 0)]); - camera->viewMatCenterY = (int32_t) lround(-m.m[Matrix_getIndex(3, 1)]); - camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; - camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; camera->ViewMatrix = m; return RValue_makeUndefined(); } From e28552603f7547139d82a8822f4f5cfc9f0affd8 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:17:21 +0200 Subject: [PATCH 03/22] fix tiny mistake --- src/vm_builtins.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index f751d522..3174a350 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3567,8 +3567,6 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t GMLReal m11 = m.m[Matrix_getIndex(1, 1)]; if (m00 != 0.0) camera->viewWidth = (int32_t) lround(GMLReal_fabs(2.0 / m00)); if (m11 != 0.0) camera->viewHeight = (int32_t) lround(GMLReal_fabs(2.0 / m11)); - camera->viewX = camera->viewMatCenterX - camera->viewWidth / 2; - camera->viewY = camera->viewMatCenterY - camera->viewHeight / 2; camera->ProjectionMatrix = m; camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); From 2a4c31d54e4fd2aafbb39331b2055471c221bc00 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 13 Jun 2026 00:45:19 +0200 Subject: [PATCH 04/22] change more things to use matricies! I kinda forgor what else I did --- src/gl/gl_renderer.c | 42 ++++++++--- src/gl/gl_renderer.h | 2 + src/gl_legacy/gl_legacy_renderer.c | 4 +- src/renderer.h | 3 +- src/runner.c | 8 ++- src/vm_builtins.c | 110 +++++++++++++++++++++++++++-- 6 files changed, 148 insertions(+), 21 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 6d1d7af0..1424354d 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -28,9 +28,9 @@ // ===[ Shader Sources ]=== static const char* baseVertexShader = - "uniform mat4 uProjection;\n" + "uniform mat4 uWorldViewProjection;\n" "void main() {\n" - " gl_Position = uProjection * vec4(aPos, 0.0, 1.0);\n" + " gl_Position = uWorldViewProjection * vec4(aPos, 0.0, 1.0);\n" " vTexCoord = aTexCoord;\n" " vColor = aColor;\n" "}\n"; @@ -687,7 +687,7 @@ static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_ // World -> clip transform for this view. Matrix4f projection; Matrix4f_viewProjection(&projection, (float) viewX, (float) viewY, (float) viewW, (float) viewH, viewAngle); - Matrix4f_flipClipY(&projection); + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); @@ -705,16 +705,30 @@ static void glEndView(Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { +static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { GLRenderer* gl = (GLRenderer*) renderer; // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); - Matrix4f projection = *worldToClip; - Matrix4f_flipClipY(&projection); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + + Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f View = *ViewMatrix; + Matrix4f Projection = *ProjectionMatrix; + + Matrix4f WorldView; + Matrix4f_multiply(&WorldView, &View, &World); + + Matrix4f WorldViewProjection; + Matrix4f_multiply(&WorldViewProjection, &View, &World); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + + renderer->gmlMatrices[MATRIX_VIEW] = View; + renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + //oh my I hope it's good enough. glShaderSettingsRefresh(renderer); - renderer->previousViewMatrix = projection; + renderer->previousViewMatrix = WorldViewProjection; } @@ -741,7 +755,7 @@ static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t p Matrix4f projection; Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); - + Matrix4f_flipClipY(&projection); renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -2175,7 +2189,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic // Normal surface bind: surface-local ortho covering the whole surface, no scissor. Matrix4f projection; Matrix4f_identity(&projection); - Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], 0.0f, (float) gl->surfaceHeight[surfaceId], -1.0f, 1.0f); + Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; @@ -2696,6 +2710,13 @@ static bool glShadersSupported(void) { return true; } +static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) { + GLRenderer* gl = (GLRenderer*) renderer; + flushBatch(gl); + renderer->gmlMatrices[MatrixType] = Matrix; + glShaderSettingsRefresh(renderer); +} + // ===[ Vtable ]=== static RendererVtable glVtable; @@ -2768,6 +2789,7 @@ Renderer* GLRenderer_create(void) { glVtable.textureSetStage = glTextureSetStage, glVtable.shaderIsCompiled = glShaderIsCompiled, glVtable.shadersSupported = glShadersSupported, + glVtable.setMatrix = glSetMatrix, gl->base.drawColor = 0xFFFFFF; // white (BGR) gl->base.drawAlpha = 1.0f; diff --git a/src/gl/gl_renderer.h b/src/gl/gl_renderer.h index 26309ed2..93028784 100644 --- a/src/gl/gl_renderer.h +++ b/src/gl/gl_renderer.h @@ -43,6 +43,8 @@ typedef struct { bool colorWriteR, colorWriteG, colorWriteB, colorWriteA; bool fogEnable; uint32_t fogColor; // BGR + float fogStart; + float fogEnd; GLuint vao, vbo, ebo; float* vertexData; // MAX_QUADS * VERTICES_PER_QUAD * FLOATS_PER_VERTEX floats diff --git a/src/gl_legacy/gl_legacy_renderer.c b/src/gl_legacy/gl_legacy_renderer.c index 67ea84fc..f11830fb 100644 --- a/src/gl_legacy/gl_legacy_renderer.c +++ b/src/gl_legacy/gl_legacy_renderer.c @@ -231,8 +231,8 @@ static void glEndView(MAYBE_UNUSED Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* worldToClip) { - Matrix4f projection = *worldToClip; +static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { + Matrix4f projection = *ProjectionMatrix; //fix it later Matrix4f_flipClipY(&projection); glMatrixMode(GL_PROJECTION); glLoadMatrixf(projection.m); diff --git a/src/renderer.h b/src/renderer.h index b18c5728..33c9d716 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -73,7 +73,7 @@ typedef struct { void (*endFrameEnd)(Renderer* renderer); void (*beginView)(Renderer* renderer, int32_t viewX, int32_t viewY, int32_t viewW, int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, float viewAngle); void (*endView)(Renderer* renderer); - void (*applyProjection)(Renderer* renderer, const Matrix4f* worldToClip); + void (*applyProjection)(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix); // GUI pass: coordinates are (0,0)..(guiW,guiH) mapped to the current view's port rect. Called after endView. // targetSurfaceId is the surface the pass renders into, or RENDER_TARGET_HOST_FRAMEBUFFER. void (*beginGUI)(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId); @@ -150,6 +150,7 @@ typedef struct { void (*textureSetStage)(Renderer* renderer, int32_t slot, uint32_t texID); bool (*shaderIsCompiled)(Renderer* renderer, int32_t shader); bool (*shadersSupported)(void); + void (*setMatrix)(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix); } RendererVtable; // ===[ Renderer Base Struct ]=== diff --git a/src/runner.c b/src/runner.c index 69cbb187..99190889 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1140,9 +1140,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh if (runner->drawBackgroundColor) renderer->vtable->clearScreen(renderer, runner->currentRoom->backgroundColor, 1.0f); - Matrix4f proj; - Matrix4f_viewProjection(&proj, (float) camera->viewX, (float) camera->viewY, (float) camera->viewWidth, (float) camera->viewHeight, camera->viewAngle); - renderer->vtable->applyProjection(renderer, &proj); + Matrix4f ViewMatrix = camera->ViewMatrix; + Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->viewCurrent = (int32_t) vi; Runner_draw(runner); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 3174a350..b4842db4 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2952,6 +2952,23 @@ static RValue builtin_matrix_build_projection_perspective_fov(MAYBE_UNUSED VMCon return RValue_makeArrayWeak(destArray); } } +static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { + int32_t Matrix = RValue_toInt32(args[0]); + return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); +} + +static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { + int32_t Matrix = RValue_toInt32(args[0]); + Matrix4f m; + matrixFromGml(&m, args[1].array); + //return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + if (ctx->runner->renderer != nullptr) { + ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); + } + + return RValue_makeUndefined(); +} + static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { if (argCount < 9 || argCount > 10) return RValue_makeUndefined(); @@ -3704,6 +3721,90 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 7) camera->speedY = RValue_toInt32(args[7]); if (argCount > 8) camera->borderX = (uint32_t) RValue_toInt32(args[8]); if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); + + //what have I done. + Matrix4f Projection; + + memset(Projection.m, 0, sizeof(Projection.m)); + Projection.m[Matrix_getIndex(0,0)] = 2.0f / RValue_toReal(args[2]); + Projection.m[Matrix_getIndex(1,1)] = 2.0f / RValue_toReal(args[3]); + Projection.m[Matrix_getIndex(2,2)] = 1.0f / (32000.0 - 0.0); + Projection.m[Matrix_getIndex(3,3)] = 1.0f; + Projection.m[Matrix_getIndex(2,3)] = 0.0 / (0.0 - 32000.0); + camera->ProjectionMatrix = Projection; + + + GMLReal xFrom = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; + GMLReal yFrom = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; + GMLReal zFrom = -16000.0; + + GMLReal xTo = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; + GMLReal yTo = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; + GMLReal zTo = 16000.0; + + GMLReal xUp = 0.0; + GMLReal yUp = 1.0; + GMLReal zUp = 0.0; + GMLReal magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + GMLReal xLook = xTo - xFrom; + GMLReal yLook = yTo - yFrom; + GMLReal zLook = zTo - zFrom; + GMLReal magLook = GMLReal_sqrt(xLook * xLook + yLook * yLook + zLook * zLook); + xLook /= magLook; + yLook /= magLook; + zLook /= magLook; + + // normalised cross product between Up and Look + GMLReal xRight = yUp * zLook - zUp * yLook; + GMLReal yRight = zUp * xLook - xUp * zLook; + GMLReal zRight = xUp * yLook - yUp * xLook; + GMLReal magRight = GMLReal_sqrt(xRight * xRight + yRight * yRight + zRight * zRight); + xRight /= magRight; + yRight /= magRight; + zRight /= magRight; + + // normalised cross product between Look and Right + xUp = yLook * zRight - zLook * yRight; + yUp = zLook * xRight - xLook * zRight; + zUp = xLook * yRight - yLook * xRight; + magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + GMLReal x, y, z; + x = xFrom * xRight + yFrom * yRight + zFrom * zRight; + y = xFrom * xUp + yFrom * yUp + zFrom * zUp; + z = xFrom * xLook + yFrom * yLook + zFrom * zLook; + + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + + ViewMatrix.m[Matrix_getIndex(0, 0)] = xRight; + ViewMatrix.m[Matrix_getIndex(1, 0)] = xUp; + ViewMatrix.m[Matrix_getIndex(2, 0)] = xLook; + + ViewMatrix.m[Matrix_getIndex(0, 1)] = yRight; + ViewMatrix.m[Matrix_getIndex(1, 1)] = yUp; + ViewMatrix.m[Matrix_getIndex(2, 1)] = yLook; + + ViewMatrix.m[Matrix_getIndex(0, 2)] = zRight; + ViewMatrix.m[Matrix_getIndex(1, 2)] = zUp; + ViewMatrix.m[Matrix_getIndex(2, 2)] = zLook; + + ViewMatrix.m[Matrix_getIndex(0, 3)] = -x; + ViewMatrix.m[Matrix_getIndex(1, 3)] = -y; + ViewMatrix.m[Matrix_getIndex(2, 3)] = -z; + camera->ViewMatrix = ViewMatrix; + + //builtin_matrix_build_lookat(ctx,args[0],args[1],RValue_makeReal(-16000.0),args[0],args[1],RValue_makeReal(16000.0), RValue_makeReal(0.0),RValue_makeReal(1.0),RValue_makeReal(0.0)) + //builtin_matrix_build_projection_ortho(ctx,args[2], args[3], RValue_makeReal(0.0), RValue_makeReal(32000.0)); + + return RValue_makeReal(id); } @@ -3759,10 +3860,8 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - Matrix4f FinalProjection; - Matrix4f_multiply(&FinalProjection, &ProjectionMatrix, &ViewMatrix); - - runner->renderer->vtable->applyProjection(runner->renderer, &FinalProjection); + + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); } return RValue_makeUndefined(); @@ -15691,7 +15790,8 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "matrix_build_lookat", builtin_matrix_build_lookat); VM_registerBuiltin(ctx, "matrix_build_projection_ortho", builtin_matrix_build_projection_ortho); VM_registerBuiltin(ctx, "matrix_build_projection_perspective_fov", builtin_matrix_build_projection_perspective_fov); - + VM_registerBuiltin(ctx, "matrix_get", builtin_matrix_get); + VM_registerBuiltin(ctx, "matrix_set", builtin_matrix_set); // Random VM_registerBuiltin(ctx, "random", builtin_random); VM_registerBuiltin(ctx, "random_range", builtin_random_range); From caa073ea0038cfe1d21ca67510b7002b712df6f0 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 13 Jun 2026 18:57:17 +0200 Subject: [PATCH 05/22] I somehow already forgor what else I did --- src/gl/gl_renderer.c | 32 ++++--- src/matrix_math.h | 81 +++++++++++++++++ src/runner.c | 47 ++++++++++ src/runner.h | 4 +- src/vm_builtins.c | 210 +++++++++++++++---------------------------- 5 files changed, 221 insertions(+), 153 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 1424354d..6134d8f7 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -673,28 +673,21 @@ static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_ // Set viewport and scissor to the port rectangle within the FBO // FBO uses game resolution, port coordinates are in game space // OpenGL viewport Y is bottom-up, game Y is top-down - int32_t glPortY = gl->gameH - portY - portH; - glViewport(portX, glPortY, portW, portH); + + glViewport(portX, portY, portW, portH); gl->base.CPortX = portX; - gl->base.CPortY = glPortY; + gl->base.CPortY = portY; gl->base.CPortW = portW; gl->base.CPortH = portH; glEnable(GL_SCISSOR_TEST); - glScissor(portX, glPortY, portW, portH); - - // World -> clip transform for this view. - Matrix4f projection; - Matrix4f_viewProjection(&projection, (float) viewX, (float) viewY, (float) viewW, (float) viewH, viewAngle); + glScissor(portX, portY, portW, portH); - - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); if (hasVAO()) glBindVertexArray(gl->vao); - renderer->previousViewMatrix = projection; } @@ -2714,6 +2707,23 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); renderer->gmlMatrices[MatrixType] = Matrix; + //yeah just recalculate everything when we change a matrix + //TODO LATR: only allow these 3 to be changed directly, other ones should only be allowed to be calculated by the rest of the function + Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f View = renderer->gmlMatrices[MATRIX_VIEW]; + Matrix4f Projection = renderer->gmlMatrices[MATRIX_PROJECTION]; + + Matrix4f WorldView; + Matrix4f_multiply(&WorldView, &View, &World); + + Matrix4f WorldViewProjection; + Matrix4f_multiply(&WorldViewProjection, &View, &World); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + + glShaderSettingsRefresh(renderer); } diff --git a/src/matrix_math.h b/src/matrix_math.h index 240875b4..9973a092 100644 --- a/src/matrix_math.h +++ b/src/matrix_math.h @@ -52,6 +52,87 @@ static inline Matrix4f* Matrix4f_multiply(Matrix4f* dest, const Matrix4f* a, con return dest; } +static inline Matrix4f* Matrix4f_LookAt(Matrix4f* dest, float x_from, float y_from, float z_from, float x_to, float y_to, float z_to, float x_up, float y_up, float z_up) { + + double xFrom = x_from; + double yFrom = y_from; + double zFrom = z_from; + + double xTo = x_to; + double yTo = y_to; + double zTo = z_to; + + double xUp = x_up; + double yUp = y_up; + double zUp = z_up; + double magUp = sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + double xLook = xTo - xFrom; + double yLook = yTo - yFrom; + double zLook = zTo - zFrom; + double magLook = sqrt(xLook * xLook + yLook * yLook + zLook * zLook); + xLook /= magLook; + yLook /= magLook; + zLook /= magLook; + + // normalised cross product between Up and Look + double xRight = yUp * zLook - zUp * yLook; + double yRight = zUp * xLook - xUp * zLook; + double zRight = xUp * yLook - yUp * xLook; + double magRight = sqrt(xRight * xRight + yRight * yRight + zRight * zRight); + xRight /= magRight; + yRight /= magRight; + zRight /= magRight; + + // normalised cross product between Look and Right + xUp = yLook * zRight - zLook * yRight; + yUp = zLook * xRight - xLook * zRight; + zUp = xLook * yRight - yLook * xRight; + magUp = sqrt(xUp * xUp + yUp * yUp + zUp * zUp); + xUp /= magUp; + yUp /= magUp; + zUp /= magUp; + + double x, y, z; + x = xFrom * xRight + yFrom * yRight + zFrom * zRight; + y = xFrom * xUp + yFrom * yUp + zFrom * zUp; + z = xFrom * xLook + yFrom * yLook + zFrom * zLook; + + dest->m[Matrix_getIndex(0, 0)] = xRight; + dest->m[Matrix_getIndex(1, 0)] = xUp; + dest->m[Matrix_getIndex(2, 0)] = xLook; + + dest->m[Matrix_getIndex(0, 1)] = yRight; + dest->m[Matrix_getIndex(1, 1)] = yUp; + dest->m[Matrix_getIndex(2, 1)] = yLook; + + dest->m[Matrix_getIndex(0, 2)] = zRight; + dest->m[Matrix_getIndex(1, 2)] = zUp; + dest->m[Matrix_getIndex(2, 2)] = zLook; + + dest->m[Matrix_getIndex(0, 3)] = -x; + dest->m[Matrix_getIndex(1, 3)] = -y; + dest->m[Matrix_getIndex(2, 3)] = -z; + + return dest; +} + +static inline Matrix4f* Matrix4f_Orthographic(Matrix4f* dest, float width, float height, float zfar, float znear) { + + memset(dest->m, 0, sizeof(dest->m)); + dest->m[Matrix_getIndex(0,0)] = 2.0f / width; + dest->m[Matrix_getIndex(1,1)] = 2.0f / height; + dest->m[Matrix_getIndex(2,2)] = 1.0f / (zfar - znear); + dest->m[Matrix_getIndex(3,3)] = 1.0f; + + dest->m[Matrix_getIndex(2,3)] = znear / (znear - zfar); + + return dest; +} + // ===[ Orthographic Projection ]=== // Post-multiply orthographic projection onto dest: dest = dest * ortho(l, r, b, t, n, f) diff --git a/src/runner.c b/src/runner.c index 99190889..9a266576 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1026,6 +1026,19 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta int32_t guiW = runner->guiWidth > 0 ? runner->guiWidth : targetW; int32_t guiH = runner->guiHeight > 0 ? runner->guiHeight : targetH; beginGuiPass(runner, guiW, guiH, windowW, windowH, RENDER_TARGET_HOST_FRAMEBUFFER); + + //make default projection + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, (float) guiW, (float) guiH, 32000.0, 0.0); + + Matrix4f View; + float x = (float) guiW / 2; + float y = (float) guiH / 2; + Matrix4f_identity(&View); + Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); + fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_END); @@ -1169,6 +1182,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); + Matrix4f ViewMatrix = camera->ViewMatrix; + Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + //what am I even doing. + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -1187,6 +1205,18 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh expandViewAxis(0, (int32_t) runner->currentRoom->height, gameH, widescreenBaseH, &viewY, &viewH); applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); + + //make default projection + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, (float) gameW, (float) -gameH, 32000.0, 0.0); + + Matrix4f View; + float x = (float) gameW /2; + float y = (float) gameH /2; + Matrix4f_identity(&View); + Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -1321,6 +1351,23 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->speedY = roomView->speedY; camera->objectId = roomView->objectId; camera->viewAngle = 0; + //make default projection + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + + Matrix4f View; + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f_identity(&View); + Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&View, x, y, 0.0f); + Matrix4f_rotateZ(&View, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&View, -x, -y, 0.0f); + + + + camera->ProjectionMatrix = Projection; + camera->ViewMatrix = View; } // Copies the viewport (port) properties and enabled flag from parsed room data. diff --git a/src/runner.h b/src/runner.h index 87051266..2e7dbd72 100644 --- a/src/runner.h +++ b/src/runner.h @@ -146,8 +146,8 @@ typedef struct { typedef struct { bool allocated; // slot in use (default cameras: set when the room enables the view; user cameras: camera_create/destroy) - int32_t viewX; - int32_t viewY; + float viewX; + float viewY; int32_t viewWidth; int32_t viewHeight; uint32_t borderX; diff --git a/src/vm_builtins.c b/src/vm_builtins.c index b4842db4..7d7ec2ed 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -217,6 +217,21 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } +static void UpdateCamera(GMLCamera* camera) { + + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + camera->ViewMatrix = ViewMatrix; + +} + + // ===[ BUILT-IN VARIABLE GET/SET ]=== static bool isValidAlarmIndex(int alarmIndex) { @@ -1567,22 +1582,34 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId // View properties case BUILTIN_VAR_VIEW_XVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewX = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewX = RValue_toReal(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_YVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewY = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewY = RValue_toInt32(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_WVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewWidth = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewWidth = RValue_toInt32(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_HVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewHeight = RValue_toInt32(val); + if (camera != nullptr) { + camera->viewHeight = RValue_toInt32(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_XPORT: @@ -1608,7 +1635,10 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId return; case BUILTIN_VAR_VIEW_ANGLE: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); - if (camera != nullptr) camera->viewAngle = (float) RValue_toReal(val); + if (camera != nullptr) { + camera->viewAngle = (float) RValue_toReal(val); + UpdateCamera(camera); + } return; } case BUILTIN_VAR_VIEW_HBORDER: { @@ -2901,14 +2931,7 @@ static RValue builtin_matrix_build_projection_ortho(MAYBE_UNUSED VMContext *ctx, if (toPrevMatrix && !rvalueIsMatrix(args[4])) return RValue_makeUndefined(); Matrix4f mat; - - memset(mat.m, 0, sizeof(mat.m)); - mat.m[Matrix_getIndex(0,0)] = 2.0f / width; - mat.m[Matrix_getIndex(1,1)] = 2.0f / height; - mat.m[Matrix_getIndex(2,2)] = 1.0f / (zfar - znear); - mat.m[Matrix_getIndex(3,3)] = 1.0f; - - mat.m[Matrix_getIndex(2,3)] = znear / (znear - zfar); + Matrix4f_Orthographic(&mat, width, height, zfar, znear); if (!toPrevMatrix) { return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &mat)); @@ -2961,7 +2984,7 @@ static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int3 int32_t Matrix = RValue_toInt32(args[0]); Matrix4f m; matrixFromGml(&m, args[1].array); - //return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + //add safe guards or whatever itis if (ctx->runner->renderer != nullptr) { ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); } @@ -2969,7 +2992,6 @@ static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int3 return RValue_makeUndefined(); } - static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { if (argCount < 9 || argCount > 10) return RValue_makeUndefined(); @@ -2984,60 +3006,11 @@ static RValue builtin_matrix_build_lookat(MAYBE_UNUSED VMContext *ctx, RValue *a GMLReal xUp = RValue_toReal(args[6]); GMLReal yUp = RValue_toReal(args[7]); GMLReal zUp = RValue_toReal(args[8]); - GMLReal magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal xLook = xTo - xFrom; - GMLReal yLook = yTo - yFrom; - GMLReal zLook = zTo - zFrom; - GMLReal magLook = GMLReal_sqrt(xLook * xLook + yLook * yLook + zLook * zLook); - xLook /= magLook; - yLook /= magLook; - zLook /= magLook; - - // normalised cross product between Up and Look - GMLReal xRight = yUp * zLook - zUp * yLook; - GMLReal yRight = zUp * xLook - xUp * zLook; - GMLReal zRight = xUp * yLook - yUp * xLook; - GMLReal magRight = GMLReal_sqrt(xRight * xRight + yRight * yRight + zRight * zRight); - xRight /= magRight; - yRight /= magRight; - zRight /= magRight; - - // normalised cross product between Look and Right - xUp = yLook * zRight - zLook * yRight; - yUp = zLook * xRight - xLook * zRight; - zUp = xLook * yRight - yLook * xRight; - magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal x, y, z; - x = xFrom * xRight + yFrom * yRight + zFrom * zRight; - y = xFrom * xUp + yFrom * yUp + zFrom * zUp; - z = xFrom * xLook + yFrom * yLook + zFrom * zLook; Matrix4f matrix; Matrix4f_identity(&matrix); - matrix.m[Matrix_getIndex(0, 0)] = xRight; - matrix.m[Matrix_getIndex(1, 0)] = xUp; - matrix.m[Matrix_getIndex(2, 0)] = xLook; - - matrix.m[Matrix_getIndex(0, 1)] = yRight; - matrix.m[Matrix_getIndex(1, 1)] = yUp; - matrix.m[Matrix_getIndex(2, 1)] = yLook; - - matrix.m[Matrix_getIndex(0, 2)] = zRight; - matrix.m[Matrix_getIndex(1, 2)] = zUp; - matrix.m[Matrix_getIndex(2, 2)] = zLook; - - matrix.m[Matrix_getIndex(0, 3)] = -x; - matrix.m[Matrix_getIndex(1, 3)] = -y; - matrix.m[Matrix_getIndex(2, 3)] = -z; + Matrix4f_LookAt(&matrix, xFrom, yFrom, zFrom, xTo, yTo, zTo, xUp, yUp, zUp); bool toPrevMatrix = argCount == 10; GMLArray *destArray = toPrevMatrix ? args[9].array : nullptr; @@ -3540,8 +3513,17 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - camera->viewX = RValue_toInt32(args[1]); - camera->viewY = RValue_toInt32(args[2]); + camera->viewX = RValue_toReal(args[1]); + camera->viewY = RValue_toReal(args[2]); + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + camera->ViewMatrix = ViewMatrix; } return RValue_makeUndefined(); } @@ -3658,7 +3640,19 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (2 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) camera->viewAngle = (float) RValue_toReal(args[1]); + if (camera != nullptr) + { + camera->viewAngle = (float) RValue_toReal(args[1]); + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f ViewMatrix; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + camera->ViewMatrix = ViewMatrix; + } return RValue_makeUndefined(); } @@ -3711,8 +3705,8 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (0 > id) return RValue_makeReal(-1); GMLCamera* camera = Runner_getCameraById(runner, id); // camera_create_view(room_x, room_y, room_w, room_h, [angle, object, x_speed, y_speed, x_border, y_border]) - if (argCount > 0) camera->viewX = RValue_toInt32(args[0]); - if (argCount > 1) camera->viewY = RValue_toInt32(args[1]); + if (argCount > 0) camera->viewX = RValue_toReal(args[0]); + if (argCount > 1) camera->viewY = RValue_toReal(args[1]); if (argCount > 2) camera->viewWidth = RValue_toInt32(args[2]); if (argCount > 3) camera->viewHeight = RValue_toInt32(args[3]); if (argCount > 4) camera->viewAngle = (float) RValue_toReal(args[4]); @@ -3722,83 +3716,19 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 8) camera->borderX = (uint32_t) RValue_toInt32(args[8]); if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - //what have I done. - Matrix4f Projection; - memset(Projection.m, 0, sizeof(Projection.m)); - Projection.m[Matrix_getIndex(0,0)] = 2.0f / RValue_toReal(args[2]); - Projection.m[Matrix_getIndex(1,1)] = 2.0f / RValue_toReal(args[3]); - Projection.m[Matrix_getIndex(2,2)] = 1.0f / (32000.0 - 0.0); - Projection.m[Matrix_getIndex(3,3)] = 1.0f; - Projection.m[Matrix_getIndex(2,3)] = 0.0 / (0.0 - 32000.0); + Matrix4f Projection; + Matrix4f_Orthographic(&Projection, camera->viewWidth, -camera->viewHeight, 32000.0, 0.0); camera->ProjectionMatrix = Projection; + //we will look at the center, okay? + float x = RValue_toReal(args[0]) + RValue_toReal(args[2])/2; + float y = RValue_toReal(args[1]) + RValue_toReal(args[3])/2; - GMLReal xFrom = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; - GMLReal yFrom = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; - GMLReal zFrom = -16000.0; - - GMLReal xTo = RValue_toReal(args[0]) + RValue_toReal(args[2])/2.0f; - GMLReal yTo = RValue_toReal(args[1]) + RValue_toReal(args[3])/2.0f; - GMLReal zTo = 16000.0; - - GMLReal xUp = 0.0; - GMLReal yUp = 1.0; - GMLReal zUp = 0.0; - GMLReal magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal xLook = xTo - xFrom; - GMLReal yLook = yTo - yFrom; - GMLReal zLook = zTo - zFrom; - GMLReal magLook = GMLReal_sqrt(xLook * xLook + yLook * yLook + zLook * zLook); - xLook /= magLook; - yLook /= magLook; - zLook /= magLook; - - // normalised cross product between Up and Look - GMLReal xRight = yUp * zLook - zUp * yLook; - GMLReal yRight = zUp * xLook - xUp * zLook; - GMLReal zRight = xUp * yLook - yUp * xLook; - GMLReal magRight = GMLReal_sqrt(xRight * xRight + yRight * yRight + zRight * zRight); - xRight /= magRight; - yRight /= magRight; - zRight /= magRight; - - // normalised cross product between Look and Right - xUp = yLook * zRight - zLook * yRight; - yUp = zLook * xRight - xLook * zRight; - zUp = xLook * yRight - yLook * xRight; - magUp = GMLReal_sqrt(xUp * xUp + yUp * yUp + zUp * zUp); - xUp /= magUp; - yUp /= magUp; - zUp /= magUp; - - GMLReal x, y, z; - x = xFrom * xRight + yFrom * yRight + zFrom * zRight; - y = xFrom * xUp + yFrom * yUp + zFrom * zUp; - z = xFrom * xLook + yFrom * yLook + zFrom * zLook; - Matrix4f ViewMatrix; Matrix4f_identity(&ViewMatrix); - ViewMatrix.m[Matrix_getIndex(0, 0)] = xRight; - ViewMatrix.m[Matrix_getIndex(1, 0)] = xUp; - ViewMatrix.m[Matrix_getIndex(2, 0)] = xLook; - - ViewMatrix.m[Matrix_getIndex(0, 1)] = yRight; - ViewMatrix.m[Matrix_getIndex(1, 1)] = yUp; - ViewMatrix.m[Matrix_getIndex(2, 1)] = yLook; - - ViewMatrix.m[Matrix_getIndex(0, 2)] = zRight; - ViewMatrix.m[Matrix_getIndex(1, 2)] = zUp; - ViewMatrix.m[Matrix_getIndex(2, 2)] = zLook; - - ViewMatrix.m[Matrix_getIndex(0, 3)] = -x; - ViewMatrix.m[Matrix_getIndex(1, 3)] = -y; - ViewMatrix.m[Matrix_getIndex(2, 3)] = -z; + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); camera->ViewMatrix = ViewMatrix; //builtin_matrix_build_lookat(ctx,args[0],args[1],RValue_makeReal(-16000.0),args[0],args[1],RValue_makeReal(16000.0), RValue_makeReal(0.0),RValue_makeReal(1.0),RValue_makeReal(0.0)) From a5d45233a072052eac29a741dbb54aefc7a43892 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 13 Jun 2026 20:09:53 +0200 Subject: [PATCH 06/22] clean up a little bit --- src/runner.h | 1 - src/vm_builtins.c | 23 ++--------------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/runner.h b/src/runner.h index 2e7dbd72..d01fb31b 100644 --- a/src/runner.h +++ b/src/runner.h @@ -156,7 +156,6 @@ typedef struct { int32_t speedY; int32_t objectId; // follow target (object index), -1 = none float viewAngle; - Matrix4f ViewMatrix; Matrix4f ProjectionMatrix; } GMLCamera; diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 7d7ec2ed..90ced8f2 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3515,15 +3515,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - camera->ViewMatrix = ViewMatrix; + UpdateCamera(camera); } return RValue_makeUndefined(); } @@ -3645,13 +3637,7 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ camera->viewAngle = (float) RValue_toReal(args[1]); float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - camera->ViewMatrix = ViewMatrix; + UpdateCamera(camera); } return RValue_makeUndefined(); } @@ -3727,14 +3713,9 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a Matrix4f ViewMatrix; Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); camera->ViewMatrix = ViewMatrix; - //builtin_matrix_build_lookat(ctx,args[0],args[1],RValue_makeReal(-16000.0),args[0],args[1],RValue_makeReal(16000.0), RValue_makeReal(0.0),RValue_makeReal(1.0),RValue_makeReal(0.0)) - //builtin_matrix_build_projection_ortho(ctx,args[2], args[3], RValue_makeReal(0.0), RValue_makeReal(32000.0)); - - return RValue_makeReal(id); } From 7fccb1e9a74a699e8d1b5850afd93b86e95f8e54 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 11:43:40 +0200 Subject: [PATCH 07/22] make rendering to surfaces work in a hacky way --- src/gl/gl_renderer.c | 46 +++++++++++++++++++++++++++------------- src/renderer.h | 4 ++++ src/runner.c | 50 +++++++++++++++++++++++++++++++------------- src/vm_builtins.c | 13 +----------- 4 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 6134d8f7..5ad41de4 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -720,9 +720,7 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,con renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; //oh my I hope it's good enough. - glShaderSettingsRefresh(renderer); - renderer->previousViewMatrix = WorldViewProjection; - + glShaderSettingsRefresh(renderer); } static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { @@ -746,10 +744,10 @@ static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t p glEnable(GL_SCISSOR_TEST); - Matrix4f projection; - Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); - Matrix4f_flipClipY(&projection); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + //Matrix4f projection; + //Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); + //Matrix4f_flipClipY(&projection); + //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -839,11 +837,11 @@ static void glClearScreen(Renderer* renderer, uint32_t color, float alpha) { float b = (float) BGR_B(color) / 255.0f; // GML draw_clear ignores the active scissor and clears the whole target. Disable scissor for the clear and restore it after. - GLboolean scissorWasEnabled = glIsEnabled(GL_SCISSOR_TEST); - if (scissorWasEnabled) glDisable(GL_SCISSOR_TEST); + //GLboolean scissorWasEnabled = glIsEnabled(GL_SCISSOR_TEST); + //if (scissorWasEnabled) glDisable(GL_SCISSOR_TEST); glClearColor(r, g, b, alpha); glClear(GL_COLOR_BUFFER_BIT); - if (scissorWasEnabled) glEnable(GL_SCISSOR_TEST); + //if (scissorWasEnabled) glEnable(GL_SCISSOR_TEST); } // Lazily decodes and uploads a TXTR page on first access. @@ -2174,18 +2172,36 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->runner->applicationSurfaceId && implicitApplicationSurface) { glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = renderer->previousViewMatrix; + glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); glShaderSettingsRefresh(renderer); return true; } // Normal surface bind: surface-local ortho covering the whole surface, no scissor. - Matrix4f projection; - Matrix4f_identity(&projection); - Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); + //Matrix4f projection; + //Matrix4f_identity(&projection); + //Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); + //glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); + //glDisable(GL_SCISSOR_TEST); + //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + if (surfaceId == renderer->V_SurfaceID) { + glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); + + } else { + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); + + Matrix4f ViewMatrix; + float x = (float) gl->surfaceWidth[surfaceId] /2; + float y = (float) gl->surfaceHeight[surfaceId] /2; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + } + + glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; glShaderSettingsRefresh(renderer); return true; diff --git a/src/renderer.h b/src/renderer.h index 33c9d716..fd917ba0 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -9,6 +9,7 @@ #include "data_win.h" #include "instance.h" + // GameMaker Blend Modes #define bm_complex -1 @@ -173,6 +174,9 @@ struct Renderer { Runner* runner; Matrix4f gmlMatrices[MATRICES_MAX]; int32_t currentShader; + Matrix4f V_ViewMatrix; + Matrix4f V_ProjectionMatrix; + int32_t V_SurfaceID; }; // ===[ Shared Helpers (platform-agnostic) ]=== diff --git a/src/runner.c b/src/runner.c index 9a266576..06945beb 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1028,16 +1028,19 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta beginGuiPass(runner, guiW, guiH, windowW, windowH, RENDER_TARGET_HOST_FRAMEBUFFER); //make default projection - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, (float) guiW, (float) guiH, 32000.0, 0.0); + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - Matrix4f View; + Matrix4f ViewMatrix; float x = (float) guiW / 2; float y = (float) guiH / 2; - Matrix4f_identity(&View); - Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->renderer->V_ViewMatrix = ViewMatrix; + runner->renderer->V_ProjectionMatrix = ProjectionMatrix; + runner->renderer->V_SurfaceID = -1; fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); @@ -1155,7 +1158,9 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - + renderer->V_ViewMatrix = ViewMatrix; + renderer->V_ProjectionMatrix = ProjectionMatrix; + renderer->V_SurfaceID = view->surfaceId; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); @@ -1184,7 +1189,9 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - //what am I even doing. + renderer->V_ViewMatrix = ViewMatrix; + renderer->V_ProjectionMatrix = ProjectionMatrix; + renderer->V_SurfaceID = -1; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); @@ -1207,16 +1214,23 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); //make default projection - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, (float) gameW, (float) -gameH, 32000.0, 0.0); + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) gameW, (float) -gameH, 32000.0, 0.0); - Matrix4f View; + Matrix4f ViewMatrix; float x = (float) gameW /2; float y = (float) gameH /2; - Matrix4f_identity(&View); - Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - runner->renderer->vtable->applyProjection(runner->renderer, &View, &Projection); + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + renderer->V_ViewMatrix = ViewMatrix; + renderer->V_ProjectionMatrix = ProjectionMatrix; + if (camera != nullptr) { + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + } + + renderer->V_SurfaceID = -1; + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -3932,6 +3946,9 @@ bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { runner->surfaceStack[slot] = surfaceID; runner->renderer->vtable->flush(runner->renderer); + GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); + runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; + runner->renderer->V_ViewMatrix = camera->ViewMatrix; return runner->renderer->vtable->setRenderTarget(runner->renderer, surfaceID, false); } @@ -3946,6 +3963,9 @@ bool Runner_surfaceResetTarget(Runner* runner) { int32_t newTop = findStackTop(runner); int32_t newTarget = newTop == -1 ? runner->applicationSurfaceId : runner->surfaceStack[newTop]; + GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); + runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; + runner->renderer->V_ViewMatrix = camera->ViewMatrix; runner->renderer->vtable->setRenderTarget(runner->renderer, newTarget, newTop == -1); if (newTop == -1 && runner->inGuiPass) { // Inside Pre Draw / Post Draw / Draw GUI the base target is the GUI pass target with the GUI projection, not the room view. diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 90ced8f2..b2f85e53 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3703,18 +3703,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, camera->viewWidth, -camera->viewHeight, 32000.0, 0.0); - camera->ProjectionMatrix = Projection; - //we will look at the center, okay? - float x = RValue_toReal(args[0]) + RValue_toReal(args[2])/2; - float y = RValue_toReal(args[1]) + RValue_toReal(args[3])/2; - - - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - camera->ViewMatrix = ViewMatrix; + UpdateCamera(camera); return RValue_makeReal(id); } From f11706695d50da4ba13dea4403a82831616f8ec5 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 15:04:47 +0200 Subject: [PATCH 08/22] add and remove some comments --- src/gl/gl_renderer.c | 10 ++-------- src/renderer.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 5ad41de4..a6521f61 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -2177,16 +2177,10 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic return true; } - // Normal surface bind: surface-local ortho covering the whole surface, no scissor. - //Matrix4f projection; - //Matrix4f_identity(&projection); - //Matrix4f_ortho(&projection, 0.0f, (float) gl->surfaceWidth[surfaceId], (float) gl->surfaceHeight[surfaceId], 0.0f, -1.0f, 1.0f); - //glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); - //glDisable(GL_SCISSOR_TEST); - //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + if (surfaceId == renderer->V_SurfaceID) { + //we go back to the camera's settings for this glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); - } else { Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); diff --git a/src/renderer.h b/src/renderer.h index fd917ba0..9917ecaf 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -166,7 +166,7 @@ struct Renderer { int32_t drawValign; // 0=top, 1=middle, 2=bottom int32_t circlePrecision; // segments used by draw_circle/draw_ellipse, clamped to [4, 64] and rounded down to multiple of 4. Default 24. //It's The Simplest Way I Found To Restore Previous Thingies For Rendering SORRY - Matrix4f previousViewMatrix; + Matrix4f previousViewMatrix; //when you go fix the Legacy OpenGL renderer, please remove this, as we don't need this anymore I hope int32_t CPortX; int32_t CPortY; int32_t CPortW; From ba61c90958c8256c1a2362072963bb19e33e3502 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 20:47:16 +0200 Subject: [PATCH 09/22] I think I've made spaghetti --- src/gl/gl_renderer.c | 22 ++++++++++++++++++++++ src/renderer.h | 3 +++ src/runner.c | 4 ++++ src/runner.h | 1 + src/vm_builtins.c | 9 ++++++++- 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index a6521f61..469694aa 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -2173,6 +2173,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); + gl->base.CameraCurrent = renderer->runner->viewCurrent; glShaderSettingsRefresh(renderer); return true; } @@ -2181,6 +2182,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->V_SurfaceID) { //we go back to the camera's settings for this glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); + gl->base.CameraCurrent = renderer->runner->viewCurrent; } else { Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); @@ -2191,6 +2193,24 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + gl->base.CameraCurrent = SURFACE_CAMERA; + + GMLCamera* camera = &renderer->runner->surfaceCamera; + + camera->allocated = true; + camera->viewX = 0.0; + camera->viewY = 0.0; + camera->viewWidth = gl->surfaceWidth[surfaceId]; + camera->viewHeight = gl->surfaceHeight[surfaceId]; + camera->borderX = 0; + camera->borderY = 0; + camera->speedX = 0; + camera->speedY = 0; + camera->objectId = -1; + camera->viewAngle = 0; + + camera->ProjectionMatrix = ProjectionMatrix; + camera->ViewMatrix = ViewMatrix; } @@ -2818,5 +2838,7 @@ Renderer* GLRenderer_create(void) { gl->base.drawValign = 0; gl->base.circlePrecision = 24; gl->base.currentShader = -1; + gl->base.V_SurfaceID = -1; + gl->base.CameraCurrent = 0; return (Renderer*) gl; } diff --git a/src/renderer.h b/src/renderer.h index 9917ecaf..ba55f7c9 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -43,6 +43,8 @@ #define MAX_TEXTURE_STAGES 8 +#define SURFACE_CAMERA 8192 + // Sentinel returned by ensureApplicationSurface on platforms that don't back the application_surface with a real entry in the renderer's surface table. // // Also used as the initial value of Runner.applicationSurfaceId before the first ensure call. @@ -177,6 +179,7 @@ struct Renderer { Matrix4f V_ViewMatrix; Matrix4f V_ProjectionMatrix; int32_t V_SurfaceID; + int32_t CameraCurrent; }; // ===[ Shared Helpers (platform-agnostic) ]=== diff --git a/src/runner.c b/src/runner.c index 06945beb..d48cba95 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1165,6 +1165,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; + runner->renderer->CameraCurrent = runner->viewCurrent; Runner_draw(runner); renderer->vtable->flush(renderer); @@ -1185,6 +1186,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float viewAngle = camera->viewAngle; runner->viewCurrent = (int32_t) vi; + runner->renderer->CameraCurrent = runner->viewCurrent; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); Matrix4f ViewMatrix = camera->ViewMatrix; @@ -1241,6 +1243,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh // Reset view_current to 0 so non-Draw events (Step, Alarm, Create) see view_current = 0 runner->viewCurrent = 0; + runner->renderer->CameraCurrent = runner->viewCurrent; } // ===[ Instance Creation Helper ]=== @@ -1342,6 +1345,7 @@ GMLCamera* Runner_getCameraById(Runner* runner, int32_t id) { if (0 > id) return nullptr; else if (MAX_DEFAULT_ROOM_CAMERAS > id) camera = &runner->defaultCameras[id]; else if (MAX_CAMERAS > id) camera = &runner->userCameras[id - MAX_DEFAULT_ROOM_CAMERAS]; + else if (id == 8192) camera = &runner->surfaceCamera; else return nullptr; if (!camera->allocated) return nullptr; return camera; diff --git a/src/runner.h b/src/runner.h index d01fb31b..1a6fcd32 100644 --- a/src/runner.h +++ b/src/runner.h @@ -473,6 +473,7 @@ struct Runner { RuntimeView views[MAX_VIEWS]; GMLCamera defaultCameras[MAX_DEFAULT_ROOM_CAMERAS]; GMLCamera userCameras[MAX_USER_CAMERAS]; + GMLCamera surfaceCamera; RunnerGamepadState* gamepads; RuntimeBackground backgrounds[8]; uint32_t backgroundColor; // runtime-mutable (BGR format) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index b2f85e53..81467cc5 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -227,7 +227,13 @@ static void UpdateCamera(GMLCamera* camera) { Matrix4f_translate(&ViewMatrix, x, y, 0.0f); Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; } @@ -3739,7 +3745,8 @@ static RValue builtin_view_set_camera(VMContext* ctx, RValue* args, int32_t argC static RValue builtin_camera_get_active(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; if (runner->viewCurrent >= 0 && MAX_VIEWS > runner->viewCurrent) { - return RValue_makeReal(runner->views[runner->viewCurrent].cameraId); + //return RValue_makeReal(runner->views[runner->viewCurrent].cameraId); + return RValue_makeReal(runner->renderer->CameraCurrent); } return RValue_makeReal(-1); } From d1b97cd00ad2022aeba1e3d795cbde963415dd35 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 14 Jun 2026 22:34:50 +0200 Subject: [PATCH 10/22] clean up a little bit --- src/gl/gl_renderer.c | 5 ++--- src/gl/gl_renderer.h | 2 -- src/renderer.h | 1 - src/runner.c | 6 +++--- src/vm_builtins.c | 16 ++-------------- 5 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 469694aa..84797271 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -837,11 +837,10 @@ static void glClearScreen(Renderer* renderer, uint32_t color, float alpha) { float b = (float) BGR_B(color) / 255.0f; // GML draw_clear ignores the active scissor and clears the whole target. Disable scissor for the clear and restore it after. - //GLboolean scissorWasEnabled = glIsEnabled(GL_SCISSOR_TEST); - //if (scissorWasEnabled) glDisable(GL_SCISSOR_TEST); + //No it doesn't? glClearColor(r, g, b, alpha); glClear(GL_COLOR_BUFFER_BIT); - //if (scissorWasEnabled) glEnable(GL_SCISSOR_TEST); + } // Lazily decodes and uploads a TXTR page on first access. diff --git a/src/gl/gl_renderer.h b/src/gl/gl_renderer.h index 93028784..26309ed2 100644 --- a/src/gl/gl_renderer.h +++ b/src/gl/gl_renderer.h @@ -43,8 +43,6 @@ typedef struct { bool colorWriteR, colorWriteG, colorWriteB, colorWriteA; bool fogEnable; uint32_t fogColor; // BGR - float fogStart; - float fogEnd; GLuint vao, vbo, ebo; float* vertexData; // MAX_QUADS * VERTICES_PER_QUAD * FLOATS_PER_VERTEX floats diff --git a/src/renderer.h b/src/renderer.h index ba55f7c9..6b85432f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -9,7 +9,6 @@ #include "data_win.h" #include "instance.h" - // GameMaker Blend Modes #define bm_complex -1 diff --git a/src/runner.c b/src/runner.c index d48cba95..8132bc08 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1165,7 +1165,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->viewCurrent; + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; Runner_draw(runner); renderer->vtable->flush(renderer); @@ -1186,7 +1186,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float viewAngle = camera->viewAngle; runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->viewCurrent; + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); Matrix4f ViewMatrix = camera->ViewMatrix; @@ -1243,7 +1243,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh // Reset view_current to 0 so non-Draw events (Step, Alarm, Create) see view_current = 0 runner->viewCurrent = 0; - runner->renderer->CameraCurrent = runner->viewCurrent; + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; } // ===[ Instance Creation Helper ]=== diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 81467cc5..0edbbfc6 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3559,11 +3559,6 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - // Orthographic projection: m[0,0] = 2/width, m[1,1] = 2/height. - GMLReal m00 = m.m[Matrix_getIndex(0, 0)]; - GMLReal m11 = m.m[Matrix_getIndex(1, 1)]; - if (m00 != 0.0) camera->viewWidth = (int32_t) lround(GMLReal_fabs(2.0 / m00)); - if (m11 != 0.0) camera->viewHeight = (int32_t) lround(GMLReal_fabs(2.0 / m11)); camera->ProjectionMatrix = m; camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); @@ -3641,8 +3636,6 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(args[1]); - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; UpdateCamera(camera); } return RValue_makeUndefined(); @@ -3763,13 +3756,8 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun if (1 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) { - - Matrix4f ViewMatrix = camera->ViewMatrix; - Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - + if (camera != nullptr) { + runner->renderer->vtable->applyProjection(runner->renderer, &camera->ViewMatrix, &camera->ProjectionMatrix); } return RValue_makeUndefined(); } From cc809ab15ef63c6061c5e60fbc2f87ed6ff0b0cc Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 15 Jun 2026 22:28:24 +0200 Subject: [PATCH 11/22] remove hacks and hopefully it's good enough --- src/gl/gl_renderer.c | 32 ++++++++++++++++++++++---------- src/renderer.h | 3 --- src/runner.c | 40 +++++++++++----------------------------- src/vm_builtins.c | 23 +++++++++++------------ 4 files changed, 44 insertions(+), 54 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 84797271..850acf33 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -2162,6 +2162,15 @@ static bool glSurfaceGetPixels(Renderer* renderer, int32_t surfaceId, uint8_t* o static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implicitApplicationSurface) { GLRenderer* gl = (GLRenderer*) renderer; + flushBatch(gl); + + int32_t ViewCurrent = 0; + if (renderer->runner->viewsEnabled) { + ViewCurrent = renderer->runner->viewCurrent; + } + RuntimeView* view = &renderer->runner->views[ViewCurrent]; + gl->base.CameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); if (0 > surfaceId || (uint32_t) surfaceId >= gl->surfaceCount) return false; if (gl->surfaces[surfaceId] == 0) return false; @@ -2171,17 +2180,19 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic if (surfaceId == renderer->runner->applicationSurfaceId && implicitApplicationSurface) { glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); - gl->base.CameraCurrent = renderer->runner->viewCurrent; - glShaderSettingsRefresh(renderer); + + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + return true; } - if (surfaceId == renderer->V_SurfaceID) { - //we go back to the camera's settings for this - glApplyProjection(renderer, &renderer->V_ViewMatrix,&renderer->V_ProjectionMatrix); - gl->base.CameraCurrent = renderer->runner->viewCurrent; + if (surfaceId == view->surfaceId) { + //the surface belongs to the view we are rending, we use the view's camera. + glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); + glDisable(GL_SCISSOR_TEST); + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + return true; } else { Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); @@ -2191,7 +2202,6 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic float y = (float) gl->surfaceHeight[surfaceId] /2; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); gl->base.CameraCurrent = SURFACE_CAMERA; GMLCamera* camera = &renderer->runner->surfaceCamera; @@ -2210,12 +2220,15 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic camera->ProjectionMatrix = ProjectionMatrix; camera->ViewMatrix = ViewMatrix; + glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); + glDisable(GL_SCISSOR_TEST); + glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + return true; } glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - glShaderSettingsRefresh(renderer); return true; } @@ -2837,7 +2850,6 @@ Renderer* GLRenderer_create(void) { gl->base.drawValign = 0; gl->base.circlePrecision = 24; gl->base.currentShader = -1; - gl->base.V_SurfaceID = -1; gl->base.CameraCurrent = 0; return (Renderer*) gl; } diff --git a/src/renderer.h b/src/renderer.h index 6b85432f..352f267e 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -175,9 +175,6 @@ struct Renderer { Runner* runner; Matrix4f gmlMatrices[MATRICES_MAX]; int32_t currentShader; - Matrix4f V_ViewMatrix; - Matrix4f V_ProjectionMatrix; - int32_t V_SurfaceID; int32_t CameraCurrent; }; diff --git a/src/runner.c b/src/runner.c index 8132bc08..f0567b75 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1038,9 +1038,6 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - runner->renderer->V_ViewMatrix = ViewMatrix; - runner->renderer->V_ProjectionMatrix = ProjectionMatrix; - runner->renderer->V_SurfaceID = -1; fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); @@ -1158,9 +1155,6 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - renderer->V_ViewMatrix = ViewMatrix; - renderer->V_ProjectionMatrix = ProjectionMatrix; - renderer->V_SurfaceID = view->surfaceId; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); @@ -1191,9 +1185,6 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f ViewMatrix = camera->ViewMatrix; Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - renderer->V_ViewMatrix = ViewMatrix; - renderer->V_ProjectionMatrix = ProjectionMatrix; - renderer->V_SurfaceID = -1; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); @@ -1224,14 +1215,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float y = (float) gameH /2; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - renderer->V_ViewMatrix = ViewMatrix; - renderer->V_ProjectionMatrix = ProjectionMatrix; if (camera != nullptr) { camera->ViewMatrix = ViewMatrix; camera->ProjectionMatrix = ProjectionMatrix; } - renderer->V_SurfaceID = -1; runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); Runner_draw(runner); @@ -1345,7 +1333,7 @@ GMLCamera* Runner_getCameraById(Runner* runner, int32_t id) { if (0 > id) return nullptr; else if (MAX_DEFAULT_ROOM_CAMERAS > id) camera = &runner->defaultCameras[id]; else if (MAX_CAMERAS > id) camera = &runner->userCameras[id - MAX_DEFAULT_ROOM_CAMERAS]; - else if (id == 8192) camera = &runner->surfaceCamera; + else if (id == SURFACE_CAMERA) camera = &runner->surfaceCamera; else return nullptr; if (!camera->allocated) return nullptr; return camera; @@ -1370,22 +1358,22 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->objectId = roomView->objectId; camera->viewAngle = 0; //make default projection - Matrix4f Projection; - Matrix4f_Orthographic(&Projection, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); - Matrix4f View; + Matrix4f ViewMatrix; float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; - Matrix4f_identity(&View); - Matrix4f_LookAt(&View, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&View, x, y, 0.0f); - Matrix4f_rotateZ(&View, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&View, -x, -y, 0.0f); + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&ViewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - camera->ProjectionMatrix = Projection; - camera->ViewMatrix = View; + camera->ProjectionMatrix = ProjectionMatrix; + camera->ViewMatrix = ViewMatrix; } // Copies the viewport (port) properties and enabled flag from parsed room data. @@ -3950,9 +3938,6 @@ bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { runner->surfaceStack[slot] = surfaceID; runner->renderer->vtable->flush(runner->renderer); - GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); - runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->V_ViewMatrix = camera->ViewMatrix; return runner->renderer->vtable->setRenderTarget(runner->renderer, surfaceID, false); } @@ -3967,9 +3952,6 @@ bool Runner_surfaceResetTarget(Runner* runner) { int32_t newTop = findStackTop(runner); int32_t newTarget = newTop == -1 ? runner->applicationSurfaceId : runner->surfaceStack[newTop]; - GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); - runner->renderer->V_ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->V_ViewMatrix = camera->ViewMatrix; runner->renderer->vtable->setRenderTarget(runner->renderer, newTarget, newTop == -1); if (newTop == -1 && runner->inGuiPass) { // Inside Pre Draw / Post Draw / Draw GUI the base target is the GUI pass target with the GUI projection, not the room view. diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 0edbbfc6..f663fb43 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -217,7 +217,7 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } -static void UpdateCamera(GMLCamera* camera) { +static void UpdateCameraViewSimple(GMLCamera* camera) { float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; @@ -1590,7 +1590,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewX = RValue_toReal(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } @@ -1598,23 +1598,23 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewY = RValue_toInt32(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_WVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewWidth = RValue_toInt32(val); - UpdateCamera(camera); - } + camera->viewWidth = RValue_toInt32(val); + UpdateCameraViewSimple(camera); + } return; } case BUILTIN_VAR_VIEW_HVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewHeight = RValue_toInt32(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } @@ -1643,7 +1643,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(val); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return; } @@ -3521,7 +3521,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3636,7 +3636,7 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(args[1]); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3702,7 +3702,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - UpdateCamera(camera); + UpdateCameraViewSimple(camera); return RValue_makeReal(id); } @@ -3738,7 +3738,6 @@ static RValue builtin_view_set_camera(VMContext* ctx, RValue* args, int32_t argC static RValue builtin_camera_get_active(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; if (runner->viewCurrent >= 0 && MAX_VIEWS > runner->viewCurrent) { - //return RValue_makeReal(runner->views[runner->viewCurrent].cameraId); return RValue_makeReal(runner->renderer->CameraCurrent); } return RValue_makeReal(-1); From cfe1767dcf2feae3b8fcf9a4c85938c858623434 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Tue, 16 Jun 2026 20:55:59 +0200 Subject: [PATCH 12/22] remove more hacks and smth else I forgor --- src/gl/gl_renderer.c | 70 ++++++++++++++++++------------ src/gl_legacy/gl_legacy_renderer.c | 2 +- src/runner.c | 24 +++++++--- src/vm_builtins.c | 3 +- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 850acf33..126aa21c 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -591,6 +591,32 @@ static void glShaderSettingsRefresh(Renderer* renderer) { } } +// camera_apply: swap the active world->clip projection on the current target without touching its viewport. +static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { + GLRenderer* gl = (GLRenderer*) renderer; + + // Flush first so pending quads draw under the projection they were issued with. + flushBatch(gl); + + Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f View = *ViewMatrix; + Matrix4f Projection = *ProjectionMatrix; + + Matrix4f WorldView; + Matrix4f_multiply(&WorldView, &View, &World); + + Matrix4f WorldViewProjection; + Matrix4f_multiply(&WorldViewProjection, &View, &World); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + + renderer->gmlMatrices[MATRIX_VIEW] = View; + renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + //oh my I hope it's good enough. + glShaderSettingsRefresh(renderer); +} + static void glGpuResetShader(Renderer* renderer) { GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); @@ -664,7 +690,7 @@ static void glBeginFrame(Renderer* renderer, int32_t gameW, int32_t gameH, int32 gl->base.CPortH = gameH; } -static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_t viewW, int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, float viewAngle) { +static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UNUSED int32_t viewY, MAYBE_UNUSED int32_t viewW, MAYBE_UNUSED int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, MAYBE_UNUSED float viewAngle) { GLRenderer* gl = (GLRenderer*) renderer; gl->batchCount = 0; @@ -684,6 +710,20 @@ static void glBeginView(Renderer* renderer, int32_t viewX, int32_t viewY, int32_ glEnable(GL_SCISSOR_TEST); glScissor(portX, portY, portW, portH); + int32_t ViewCurrent = 0; + if (renderer->runner->viewsEnabled) { + ViewCurrent = renderer->runner->viewCurrent; + } + RuntimeView* view = &renderer->runner->views[ViewCurrent]; + gl->base.CameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + + //Matrix4f ViewMatrix = camera->ViewMatrix; + //Matrix4f ProjectionMatrix = camera->ProjectionMatrix; + //runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + + glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -697,33 +737,7 @@ static void glEndView(Renderer* renderer) { glDisable(GL_SCISSOR_TEST); } -// camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { - GLRenderer* gl = (GLRenderer*) renderer; - - // Flush first so pending quads draw under the projection they were issued with. - flushBatch(gl); - - Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = *ViewMatrix; - Matrix4f Projection = *ProjectionMatrix; - - Matrix4f WorldView; - Matrix4f_multiply(&WorldView, &View, &World); - - Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &View, &World); - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); - - renderer->gmlMatrices[MATRIX_VIEW] = View; - renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; - //oh my I hope it's good enough. - glShaderSettingsRefresh(renderer); -} - -static void glBeginGUI(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { +static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUSED int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { GLRenderer* gl = (GLRenderer*) renderer; gl->batchCount = 0; diff --git a/src/gl_legacy/gl_legacy_renderer.c b/src/gl_legacy/gl_legacy_renderer.c index f11830fb..d060867c 100644 --- a/src/gl_legacy/gl_legacy_renderer.c +++ b/src/gl_legacy/gl_legacy_renderer.c @@ -231,7 +231,7 @@ static void glEndView(MAYBE_UNUSED Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { +static void glApplyProjection(Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { Matrix4f projection = *ProjectionMatrix; //fix it later Matrix4f_flipClipY(&projection); glMatrixMode(GL_PROJECTION); diff --git a/src/runner.c b/src/runner.c index f0567b75..5f034ac4 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1183,10 +1183,6 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); - Matrix4f ViewMatrix = camera->ViewMatrix; - Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); @@ -1216,6 +1212,11 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); if (camera != nullptr) { + camera->viewX = 0; + camera->viewY = 0; + camera->viewWidth = gameW; + camera->viewHeight = gameH; + camera->viewAngle = 0.0; camera->ViewMatrix = ViewMatrix; camera->ProjectionMatrix = ProjectionMatrix; } @@ -3927,7 +3928,20 @@ void Runner_guiSizeChanged(Runner* runner) { runner->guiPassH = guiH; int32_t top = findStackTop(runner); bool renderingToUserSurface = (top != -1 && runner->surfaceStack[top] != runner->applicationSurfaceId); - runner->renderer->vtable->setGuiProjection(runner->renderer, guiW, guiH, runner->guiPassPortW, runner->guiPassPortH, renderingToUserSurface); + float MULT = 1.0; + if (renderingToUserSurface == true) { + MULT = -1.0; + } + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->guiPassW, (float) runner->guiPassH*MULT, 32000.0, 0.0); + + Matrix4f ViewMatrix; + float x = (float) runner->guiPassW /2; + float y = (float) runner->guiPassH /2; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); } bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index f663fb43..0e44e963 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3755,8 +3755,9 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun if (1 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) { + if (camera != nullptr) { runner->renderer->vtable->applyProjection(runner->renderer, &camera->ViewMatrix, &camera->ProjectionMatrix); + runner->renderer->CameraCurrent = RValue_toInt32(args[0]); } return RValue_makeUndefined(); } From a2435188528397268aa81798d10660e9df4364d4 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Thu, 18 Jun 2026 21:50:25 +0200 Subject: [PATCH 13/22] rebase and fix little things --- src/gl/gl_renderer.c | 37 +++++++++++++++++++++++++------------ src/runner.c | 3 ++- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 126aa21c..6650bdb2 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -303,6 +303,14 @@ static void glInit(Renderer* renderer, DataWin* dataWin) { GLRenderer* gl = (GLRenderer*) renderer; renderer->dataWin = dataWin; + Matrix4f World; + Matrix4f_identity(&World); + renderer->gmlMatrices[MATRIX_WORLD] = World; + + Matrix4f World; + Matrix4f_identity(&World); + renderer->gmlMatrices[MATRIX_WORLD] = World; + GMLShader* defaultShader = (GMLShader*)safeCalloc(1, sizeof(GMLShader)); const char* versionStr = (const char*) glGetString(GL_VERSION); fprintf(stderr, "OpenGL version: %s\n", versionStr); @@ -549,8 +557,14 @@ static void glGpuSetShader(Renderer* renderer, int32_t shaderIndex) { GLShaderUniform* gmAlphaTestEnabledUniform = findShaderUniformByName(gmlShader, "gm_AlphaTestEnabled"); GLShaderUniform* gmAlphaRefValue = findShaderUniformByName(gmlShader, "gm_AlphaRefValue"); + Matrix4f FlippedClip[MATRICES_MAX]; + for (int32_t i = 0; i < MATRICES_MAX; i++) { + FlippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&FlippedClip[i]); + } + if (gmMatricesUniform != nullptr) { - glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, renderer->gmlMatrices[0].m); + glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, FlippedClip[0].m); } if (gmFogColourUniform != nullptr) { glUniform1i(gmFogColourUniform->location, gl->fogColor); @@ -577,13 +591,18 @@ static void glShaderSettingsRefresh(Renderer* renderer) { glUseProgram(gl->defaultShaderProgram->shaderId); - GLShaderUniform* uProjection = findShaderUniformByName(gl->defaultShaderProgram, "uProjection"); + GLShaderUniform* uWorldViewProjection = findShaderUniformByName(gl->defaultShaderProgram, "uWorldViewProjection"); GLShaderUniform* uFogColor = findShaderUniformByName(gl->defaultShaderProgram, "uFogColor"); GLShaderUniform* uAlphaTestRef = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestRef"); GLShaderUniform* uAlphaTestEnabled = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestEnabled"); GLShaderUniform* uTexture = findShaderUniformByName(gl->defaultShaderProgram, "uTexture"); + Matrix4f FlippedClip[MATRICES_MAX]; + for (int32_t i = 0; i < MATRICES_MAX; i++) { + FlippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&FlippedClip[i]); + } - glUniformMatrix4fv(uProjection->location, 1, GL_FALSE, renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION].m); + glUniformMatrix4fv(uWorldViewProjection->location, 1, GL_FALSE, FlippedClip[MATRIX_WORLD_VIEW_PROJECTION].m); glUniform4f(uFogColor->location, fogR, fogG, fogB, gl->fogEnable ? 1.0f : 0.0f); glUniform1f(uAlphaTestRef->location, gl->alphaTestRef); glUniform1i(uAlphaTestEnabled->location, gl->alphaTestEnable); @@ -606,8 +625,7 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,con Matrix4f_multiply(&WorldView, &View, &World); Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &View, &World); - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); renderer->gmlMatrices[MATRIX_VIEW] = View; renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; @@ -719,11 +737,6 @@ static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UN GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); - //Matrix4f ViewMatrix = camera->ViewMatrix; - //Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - //runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - - glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -2208,6 +2221,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); return true; } else { + //camera will use full surface. Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); @@ -2773,8 +2787,7 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) Matrix4f_multiply(&WorldView, &View, &World); Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &View, &World); - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldViewProjection); + Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; diff --git a/src/runner.c b/src/runner.c index 5f034ac4..72506fdb 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1221,7 +1221,8 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh camera->ProjectionMatrix = ProjectionMatrix; } - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + renderer->vtable->beginView(renderer, fullViewX, fullViewY, fullViewW, fullViewH, 0, 0, gameW, gameH, 0.0f); + Runner_draw(runner); if (debugShowCollisionMasks) DebugOverlay_drawCollisionMasks(runner); From 62d32983e29e3810164c6ae74d41ae41aca3f1f6 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:37:16 +0200 Subject: [PATCH 14/22] remove more thing, try fix GUI kinda --- src/gl/gl_renderer.c | 42 ++++++++++++++++++++++++++++++------------ src/runner.c | 31 ++++--------------------------- src/vm_builtins.c | 16 ++++++++++++++-- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 6650bdb2..89fffbe4 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -750,7 +750,7 @@ static void glEndView(Renderer* renderer) { glDisable(GL_SCISSOR_TEST); } -static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUSED int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId) { +static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUSED int32_t guiH, int32_t portX, int32_t portY, int32_t portW, MAYBE_UNUSED int32_t portH, int32_t targetSurfaceId) { GLRenderer* gl = (GLRenderer*) renderer; gl->batchCount = 0; @@ -771,25 +771,43 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS glEnable(GL_SCISSOR_TEST); - //Matrix4f projection; - //Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); - //Matrix4f_flipClipY(&projection); - //renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; - glShaderSettingsRefresh(renderer); + gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be + //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + + Matrix4f ViewMatrix; + float x = (float) guiW /2; + float y = (float) guiH /2; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); + + glActiveTexture(GL_TEXTURE1); if (hasVAO()) glBindVertexArray(gl->vao); } -static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portW, int32_t portH, bool renderingToUserSurface) { +static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, MAYBE_UNUSED int32_t portW, MAYBE_UNUSED int32_t portH, MAYBE_UNUSED bool renderingToUserSurface) { GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); - Matrix4f projection; - Matrix4f_guiProjection(&projection, (float) guiW, (float) guiH, (float) portW, (float) portH); + // GL surfaces are stored bottom-up and draw_surface samples them with vertical flip. - // Flip the projection when we are rendering to a user surface so it comes back upright. - if (renderingToUserSurface) Matrix4f_flipClipY(&projection); - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = projection; + gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be + //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later + //yeah no I have no idea how to do the GUI + Matrix4f ProjectionMatrix; + Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + if (renderingToUserSurface) Matrix4f_flipClipY(&ProjectionMatrix); + Matrix4f ViewMatrix; + float x = (float) guiW * 0.5f; + float y = (float) guiH * 0.5f; + Matrix4f_identity(&ViewMatrix); + Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + + glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); glShaderSettingsRefresh(renderer); } diff --git a/src/runner.c b/src/runner.c index 72506fdb..7ad6cebc 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1026,19 +1026,6 @@ void Runner_drawGUI(Runner* runner, int32_t windowW, int32_t windowH, int32_t ta int32_t guiW = runner->guiWidth > 0 ? runner->guiWidth : targetW; int32_t guiH = runner->guiHeight > 0 ? runner->guiHeight : targetH; beginGuiPass(runner, guiW, guiH, windowW, windowH, RENDER_TARGET_HOST_FRAMEBUFFER); - - //make default projection - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - - Matrix4f ViewMatrix; - float x = (float) guiW / 2; - float y = (float) guiH / 2; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); - fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_BEGIN); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI); fireDrawSubtype(runner, drawables, drawableCount, DRAW_GUI_END); @@ -1160,6 +1147,9 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + + Runner_draw(runner); renderer->vtable->flush(renderer); @@ -3929,20 +3919,7 @@ void Runner_guiSizeChanged(Runner* runner) { runner->guiPassH = guiH; int32_t top = findStackTop(runner); bool renderingToUserSurface = (top != -1 && runner->surfaceStack[top] != runner->applicationSurfaceId); - float MULT = 1.0; - if (renderingToUserSurface == true) { - MULT = -1.0; - } - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->guiPassW, (float) runner->guiPassH*MULT, 32000.0, 0.0); - - Matrix4f ViewMatrix; - float x = (float) runner->guiPassW /2; - float y = (float) runner->guiPassH /2; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->renderer->vtable->setGuiProjection(runner->renderer, guiW, guiH, runner->guiPassPortW, runner->guiPassPortH, renderingToUserSurface); } bool Runner_surfaceSetTarget(Runner* runner, int32_t surfaceID) { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 0e44e963..93e09432 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2983,14 +2983,26 @@ static RValue builtin_matrix_build_projection_perspective_fov(MAYBE_UNUSED VMCon } static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { int32_t Matrix = RValue_toInt32(args[0]); - return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + if (Matrix < 0 || Matrix > 2) return RValue_makeUndefined(); + bool toPrevMatrix = argCount == 2; + GMLArray *destArray = toPrevMatrix ? args[1].array : nullptr; + if (toPrevMatrix && !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); + + if (!toPrevMatrix) { + return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + } else { + repeat (16, i) { + *GMLArray_slot(destArray, i) = RValue_makeReal(ctx->runner->renderer->gmlMatrices[Matrix].m[i]); + } + return RValue_makeArrayWeak(destArray); + } } static RValue builtin_matrix_set(MAYBE_UNUSED VMContext *ctx, RValue *args, int32_t argCount) { int32_t Matrix = RValue_toInt32(args[0]); Matrix4f m; matrixFromGml(&m, args[1].array); - //add safe guards or whatever itis + if (Matrix < 0 || Matrix > 2) return RValue_makeUndefined(); if (ctx->runner->renderer != nullptr) { ctx->runner->renderer->vtable->setMatrix(ctx->runner->renderer, Matrix, m); } From b9b2c15edd3c8b0190d2f75b55a213e93e896935 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:58:02 +0200 Subject: [PATCH 15/22] try to fix things, I wanna give up --- src/gl/gl_renderer.c | 43 ++++++++++++++++++++++++++++++++++--------- src/renderer.h | 3 ++- src/runner.c | 1 + src/runner.h | 1 + 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 89fffbe4..9d971a9b 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -770,9 +770,21 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS } glEnable(GL_SCISSOR_TEST); + //I dunno hopefully this is at least somewhat correct... + gl->base.CameraCurrent = GUI_CAMERA; + GMLCamera* camera = &renderer->runner->guiCamera; + camera->allocated = true; + camera->viewX = 0.0; + camera->viewY = 0.0; + camera->viewWidth = guiW; + camera->viewHeight = guiH; + camera->borderX = 0; + camera->borderY = 0; + camera->speedX = 0; + camera->speedY = 0; + camera->objectId = -1; + camera->viewAngle = 0; - gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be - //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); @@ -781,8 +793,9 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS float y = (float) guiH /2; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); glActiveTexture(GL_TEXTURE1); @@ -795,8 +808,20 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M flushBatch(gl); // GL surfaces are stored bottom-up and draw_surface samples them with vertical flip. - gl->base.CameraCurrent = 0; //replace this number with whatver camera ID is used for the GUI. maybe some special ID? I have no idea how it should be - //GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); use this or something later + gl->base.CameraCurrent = GUI_CAMERA; + GMLCamera* camera = &renderer->runner->guiCamera; + camera->allocated = true; + camera->viewX = 0.0; + camera->viewY = 0.0; + camera->viewWidth = guiW; + camera->viewHeight = guiH; + camera->borderX = 0; + camera->borderY = 0; + camera->speedX = 0; + camera->speedY = 0; + camera->objectId = -1; + camera->viewAngle = 0; + //yeah no I have no idea how to do the GUI Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); @@ -806,9 +831,9 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M float y = (float) guiH * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - - glApplyProjection(renderer,&ViewMatrix,&ProjectionMatrix); - glShaderSettingsRefresh(renderer); + camera->ViewMatrix = ViewMatrix; + camera->ProjectionMatrix = ProjectionMatrix; + glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); } static void glEndGUI(Renderer* renderer) { diff --git a/src/renderer.h b/src/renderer.h index 352f267e..9ca0583f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -41,7 +41,8 @@ #define MAX_VS_LIGHTS 8 #define MAX_TEXTURE_STAGES 8 - +//these 2 IDs are just IDs I simply made up, replace them with proper ones eventually oki? +#define GUI_CAMERA 4096 #define SURFACE_CAMERA 8192 // Sentinel returned by ensureApplicationSurface on platforms that don't back the application_surface with a real entry in the renderer's surface table. diff --git a/src/runner.c b/src/runner.c index 7ad6cebc..dda62163 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1326,6 +1326,7 @@ GMLCamera* Runner_getCameraById(Runner* runner, int32_t id) { else if (MAX_DEFAULT_ROOM_CAMERAS > id) camera = &runner->defaultCameras[id]; else if (MAX_CAMERAS > id) camera = &runner->userCameras[id - MAX_DEFAULT_ROOM_CAMERAS]; else if (id == SURFACE_CAMERA) camera = &runner->surfaceCamera; + else if (id == GUI_CAMERA) camera = &runner->guiCamera; else return nullptr; if (!camera->allocated) return nullptr; return camera; diff --git a/src/runner.h b/src/runner.h index 1a6fcd32..9a815048 100644 --- a/src/runner.h +++ b/src/runner.h @@ -474,6 +474,7 @@ struct Runner { GMLCamera defaultCameras[MAX_DEFAULT_ROOM_CAMERAS]; GMLCamera userCameras[MAX_USER_CAMERAS]; GMLCamera surfaceCamera; + GMLCamera guiCamera; RunnerGamepadState* gamepads; RuntimeBackground backgrounds[8]; uint32_t backgroundColor; // runtime-mutable (BGR format) From b172a18da13d3a5109fd22f46edef71bc6748f60 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sat, 20 Jun 2026 14:33:57 +0200 Subject: [PATCH 16/22] fix merge conflict --- src/gl/gl_renderer.c | 10 +++++----- src/runner.c | 35 +++++++++++++++++++---------------- src/vm_builtins.c | 2 +- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 9d971a9b..061eae49 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -789,8 +789,8 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); Matrix4f ViewMatrix; - float x = (float) guiW /2; - float y = (float) guiH /2; + float x = (float) guiW * 0.5f; + float y = (float) guiH * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); camera->ViewMatrix = ViewMatrix; @@ -2266,11 +2266,11 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic } else { //camera will use full surface. Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], (float) -gl->surfaceHeight[surfaceId], 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], -((float) gl->surfaceHeight[surfaceId]), 32000.0, 0.0); Matrix4f ViewMatrix; - float x = (float) gl->surfaceWidth[surfaceId] /2; - float y = (float) gl->surfaceHeight[surfaceId] /2; + float x = (float) gl->surfaceWidth[surfaceId] * 0.5f; + float y = (float) gl->surfaceHeight[surfaceId] * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); gl->base.CameraCurrent = SURFACE_CAMERA; diff --git a/src/runner.c b/src/runner.c index dda62163..6ad90629 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1184,28 +1184,31 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh } if (!anyViewRendered) { - // See GameMaker-HTML5's "DrawViews", in specific the !m_enableviews path - // When views aren't used, the room width/height is used - int32_t viewX, viewY, viewW, viewH; - expandViewAxis(0, (int32_t) runner->currentRoom->width, gameW, widescreenBaseW, &viewX, &viewW); - expandViewAxis(0, (int32_t) runner->currentRoom->height, gameH, widescreenBaseH, &viewY, &viewH); - applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); - renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); - + // No views enabled: render with default full-screen view. + // gameW/gameH already include the widescreen extra, shift the world origin by half of it on each grown axis so the original room stays centered and the revealed area is split evenly between the opposing edges. + runner->viewCurrent = 0; + GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); + runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + int32_t fullViewX = -(runner->widescreenExtraWidth / 2); + int32_t fullViewY = -(runner->widescreenExtraHeight / 2); + int32_t fullViewW = gameW; + int32_t fullViewH = gameH; + applyFreeCamera(runner, &fullViewX, &fullViewY, &fullViewW, &fullViewH); + //make default projection Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) gameW, (float) -gameH, 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); Matrix4f ViewMatrix; - float x = (float) gameW /2; - float y = (float) gameH /2; + float x = (float) runner->currentRoom->width * 0.5f; + float y = (float) runner->currentRoom->height * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); if (camera != nullptr) { camera->viewX = 0; camera->viewY = 0; - camera->viewWidth = gameW; - camera->viewHeight = gameH; + camera->viewWidth = runner->currentRoom->width; + camera->viewHeight = runner->currentRoom->height; camera->viewAngle = 0.0; camera->ViewMatrix = ViewMatrix; camera->ProjectionMatrix = ProjectionMatrix; @@ -1352,11 +1355,11 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->viewAngle = 0; //make default projection Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); Matrix4f ViewMatrix; - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; + float x = camera->viewX + camera->viewWidth * 0.5f; + float y = camera->viewY + camera->viewHeight * 0.5f; Matrix4f_identity(&ViewMatrix); Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); Matrix4f_translate(&ViewMatrix, x, y, 0.0f); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 93e09432..443369f2 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -229,7 +229,7 @@ static void UpdateCameraViewSimple(GMLCamera* camera) { Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, (float) -camera->viewHeight, 32000.0, 0.0); + Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); camera->ViewMatrix = ViewMatrix; From 6449e3f5118456cd52ab72402344cbd2c3bb43c2 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Sun, 21 Jun 2026 15:37:14 +0200 Subject: [PATCH 17/22] fix little oversight and PS2 build --- src/ps2/gs_renderer.c | 3 ++- src/runner.c | 17 ++++++++--------- src/vm_builtins.c | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ps2/gs_renderer.c b/src/ps2/gs_renderer.c index 027615c9..122cf366 100644 --- a/src/ps2/gs_renderer.c +++ b/src/ps2/gs_renderer.c @@ -1157,8 +1157,9 @@ static void gsEndView(MAYBE_UNUSED Renderer* renderer) { // No-op } -static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* worldToClip) { +static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { // No-op + //Um but I do feel like the PS2 should be capable of this though? } static void gsSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, MAYBE_UNUSED int32_t portW, MAYBE_UNUSED int32_t portH, MAYBE_UNUSED bool renderingToUserSurface) { diff --git a/src/runner.c b/src/runner.c index 6ad90629..65d69921 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1184,17 +1184,16 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh } if (!anyViewRendered) { - // No views enabled: render with default full-screen view. - // gameW/gameH already include the widescreen extra, shift the world origin by half of it on each grown axis so the original room stays centered and the revealed area is split evenly between the opposing edges. runner->viewCurrent = 0; GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; - int32_t fullViewX = -(runner->widescreenExtraWidth / 2); - int32_t fullViewY = -(runner->widescreenExtraHeight / 2); - int32_t fullViewW = gameW; - int32_t fullViewH = gameH; - applyFreeCamera(runner, &fullViewX, &fullViewY, &fullViewW, &fullViewH); - + // See GameMaker-HTML5's "DrawViews", in specific the !m_enableviews path + // When views aren't used, the room width/height is used + int32_t viewX, viewY, viewW, viewH; + expandViewAxis(0, (int32_t) runner->currentRoom->width, gameW, widescreenBaseW, &viewX, &viewW); + expandViewAxis(0, (int32_t) runner->currentRoom->height, gameH, widescreenBaseH, &viewY, &viewH); + applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); + //whenever somebody feels like it, do make that free cam thingy work with this //make default projection Matrix4f ProjectionMatrix; Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); @@ -1214,7 +1213,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh camera->ProjectionMatrix = ProjectionMatrix; } - renderer->vtable->beginView(renderer, fullViewX, fullViewY, fullViewW, fullViewH, 0, 0, gameW, gameH, 0.0f); + renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); Runner_draw(runner); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 443369f2..c53fc114 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -3626,6 +3626,7 @@ static RValue builtin_camera_set_view_size(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewWidth = RValue_toInt32(args[1]); camera->viewHeight = RValue_toInt32(args[2]); + UpdateCameraViewSimple(camera); } return RValue_makeUndefined(); } From 05c162762141a18445dbd4dd2920712f9436d714 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 29 Jun 2026 17:06:25 +0200 Subject: [PATCH 18/22] fix variable name casing in Matrix4f_LookAt --- src/matrix_math.h | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/matrix_math.h b/src/matrix_math.h index 9973a092..3af37907 100644 --- a/src/matrix_math.h +++ b/src/matrix_math.h @@ -52,19 +52,8 @@ static inline Matrix4f* Matrix4f_multiply(Matrix4f* dest, const Matrix4f* a, con return dest; } -static inline Matrix4f* Matrix4f_LookAt(Matrix4f* dest, float x_from, float y_from, float z_from, float x_to, float y_to, float z_to, float x_up, float y_up, float z_up) { +static inline Matrix4f* Matrix4f_LookAt(Matrix4f* dest, float xFrom, float yFrom, float zFrom, float xTo, float yTo, float zTo, float xUp, float yUp, float zUp) { - double xFrom = x_from; - double yFrom = y_from; - double zFrom = z_from; - - double xTo = x_to; - double yTo = y_to; - double zTo = z_to; - - double xUp = x_up; - double yUp = y_up; - double zUp = z_up; double magUp = sqrt(xUp * xUp + yUp * yUp + zUp * zUp); xUp /= magUp; yUp /= magUp; From 496457b47439b8d2fd2f9bca4a5b34dbd49fbf36 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 29 Jun 2026 17:32:26 +0200 Subject: [PATCH 19/22] fix variable casing --- src/gl/gl_renderer.c | 62 +++++++++++++++--------------- src/gl_legacy/gl_legacy_renderer.c | 4 +- src/ps2/gs_renderer.c | 2 +- src/renderer.h | 2 +- src/runner.c | 42 ++++++++++---------- src/runner.h | 4 +- src/vm_builtins.c | 36 ++++++++--------- 7 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 061eae49..025066a2 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -611,15 +611,15 @@ static void glShaderSettingsRefresh(Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix) { +static void glApplyProjection(Renderer* renderer, const Matrix4f* viewMatrix,const Matrix4f* projectionMatrix) { GLRenderer* gl = (GLRenderer*) renderer; // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = *ViewMatrix; - Matrix4f Projection = *ProjectionMatrix; + Matrix4f View = *viewMatrix; + Matrix4f Projection = *projectionMatrix; Matrix4f WorldView; Matrix4f_multiply(&WorldView, &View, &World); @@ -735,7 +735,7 @@ static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UN RuntimeView* view = &renderer->runner->views[ViewCurrent]; gl->base.CameraCurrent = view->cameraId; GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); glShaderSettingsRefresh(renderer); glActiveTexture(GL_TEXTURE1); @@ -785,17 +785,17 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS camera->objectId = -1; camera->viewAngle = 0; - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = (float) guiW * 0.5f; float y = (float) guiH * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); glActiveTexture(GL_TEXTURE1); @@ -823,17 +823,17 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M camera->viewAngle = 0; //yeah no I have no idea how to do the GUI - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); - if (renderingToUserSurface) Matrix4f_flipClipY(&ProjectionMatrix); - Matrix4f ViewMatrix; + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) guiW, (float) guiH, 32000.0, 0.0); + if (renderingToUserSurface) Matrix4f_flipClipY(&projectionMatrix); + Matrix4f viewMatrix; float x = (float) guiW * 0.5f; float y = (float) guiH * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); } static void glEndGUI(Renderer* renderer) { @@ -2251,7 +2251,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic glViewport(gl->base.CPortX, gl->base.CPortY, gl->base.CPortW, gl->base.CPortH); glEnable(GL_SCISSOR_TEST); - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); return true; } @@ -2261,18 +2261,18 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic //the surface belongs to the view we are rending, we use the view's camera. glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - glApplyProjection(renderer,&camera->ViewMatrix,&camera->ProjectionMatrix); + glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); return true; } else { //camera will use full surface. - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) gl->surfaceWidth[surfaceId], -((float) gl->surfaceHeight[surfaceId]), 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) gl->surfaceWidth[surfaceId], -((float) gl->surfaceHeight[surfaceId]), 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = (float) gl->surfaceWidth[surfaceId] * 0.5f; float y = (float) gl->surfaceHeight[surfaceId] * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); gl->base.CameraCurrent = SURFACE_CAMERA; GMLCamera* camera = &renderer->runner->surfaceCamera; @@ -2289,11 +2289,11 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic camera->objectId = -1; camera->viewAngle = 0; - camera->ProjectionMatrix = ProjectionMatrix; - camera->ViewMatrix = ViewMatrix; + camera->projectionMatrix = projectionMatrix; + camera->viewMatrix = viewMatrix; glViewport(0, 0, gl->surfaceWidth[surfaceId], gl->surfaceHeight[surfaceId]); glDisable(GL_SCISSOR_TEST); - glApplyProjection(renderer, &ViewMatrix,&ProjectionMatrix); + glApplyProjection(renderer, &viewMatrix,&projectionMatrix); return true; } diff --git a/src/gl_legacy/gl_legacy_renderer.c b/src/gl_legacy/gl_legacy_renderer.c index d060867c..b072ddd1 100644 --- a/src/gl_legacy/gl_legacy_renderer.c +++ b/src/gl_legacy/gl_legacy_renderer.c @@ -231,8 +231,8 @@ static void glEndView(MAYBE_UNUSED Renderer* renderer) { } // camera_apply: swap the active world->clip projection on the current target without touching its viewport. -static void glApplyProjection(Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { - Matrix4f projection = *ProjectionMatrix; //fix it later +static void glApplyProjection(Renderer* renderer, MAYBE_UNUSED const Matrix4f* viewMatrix, MAYBE_UNUSED const Matrix4f* projectionMatrix) { + Matrix4f projection = *projectionMatrix; //fix it later Matrix4f_flipClipY(&projection); glMatrixMode(GL_PROJECTION); glLoadMatrixf(projection.m); diff --git a/src/ps2/gs_renderer.c b/src/ps2/gs_renderer.c index 122cf366..61beeea5 100644 --- a/src/ps2/gs_renderer.c +++ b/src/ps2/gs_renderer.c @@ -1157,7 +1157,7 @@ static void gsEndView(MAYBE_UNUSED Renderer* renderer) { // No-op } -static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* ViewMatrix, MAYBE_UNUSED const Matrix4f* ProjectionMatrix) { +static void gsApplyProjection(MAYBE_UNUSED Renderer* renderer, MAYBE_UNUSED const Matrix4f* viewMatrix, MAYBE_UNUSED const Matrix4f* projectionMatrix) { // No-op //Um but I do feel like the PS2 should be capable of this though? } diff --git a/src/renderer.h b/src/renderer.h index 9ca0583f..24270024 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -76,7 +76,7 @@ typedef struct { void (*endFrameEnd)(Renderer* renderer); void (*beginView)(Renderer* renderer, int32_t viewX, int32_t viewY, int32_t viewW, int32_t viewH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, float viewAngle); void (*endView)(Renderer* renderer); - void (*applyProjection)(Renderer* renderer, const Matrix4f* ViewMatrix,const Matrix4f* ProjectionMatrix); + void (*applyProjection)(Renderer* renderer, const Matrix4f* viewMatrix,const Matrix4f* projectionMatrix); // GUI pass: coordinates are (0,0)..(guiW,guiH) mapped to the current view's port rect. Called after endView. // targetSurfaceId is the surface the pass renders into, or RENDER_TARGET_HOST_FRAMEBUFFER. void (*beginGUI)(Renderer* renderer, int32_t guiW, int32_t guiH, int32_t portX, int32_t portY, int32_t portW, int32_t portH, int32_t targetSurfaceId); diff --git a/src/runner.c b/src/runner.c index 65d69921..80ecd54a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1140,14 +1140,14 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh if (runner->drawBackgroundColor) renderer->vtable->clearScreen(renderer, runner->currentRoom->backgroundColor, 1.0f); - Matrix4f ViewMatrix = camera->ViewMatrix; - Matrix4f ProjectionMatrix = camera->ProjectionMatrix; - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + Matrix4f viewMatrix = camera->viewMatrix; + Matrix4f projectionMatrix = camera->projectionMatrix; + runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); runner->viewCurrent = (int32_t) vi; runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; - runner->renderer->vtable->applyProjection(runner->renderer, &ViewMatrix, &ProjectionMatrix); + runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); Runner_draw(runner); @@ -1195,22 +1195,22 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh applyFreeCamera(runner, &viewX, &viewY, &viewW, &viewH); //whenever somebody feels like it, do make that free cam thingy work with this //make default projection - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) runner->currentRoom->width, -((float) runner->currentRoom->height), 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = (float) runner->currentRoom->width * 0.5f; float y = (float) runner->currentRoom->height * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); if (camera != nullptr) { camera->viewX = 0; camera->viewY = 0; camera->viewWidth = runner->currentRoom->width; camera->viewHeight = runner->currentRoom->height; camera->viewAngle = 0.0; - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; } renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, 0, 0, gameW, gameH, 0); @@ -1353,22 +1353,22 @@ static void initDefaultCameraFromRoomView(GMLCamera* camera, RoomView* roomView) camera->objectId = roomView->objectId; camera->viewAngle = 0; //make default projection - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - Matrix4f ViewMatrix; + Matrix4f viewMatrix; float x = camera->viewX + camera->viewWidth * 0.5f; float y = camera->viewY + camera->viewHeight * 0.5f; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&viewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); - camera->ProjectionMatrix = ProjectionMatrix; - camera->ViewMatrix = ViewMatrix; + camera->projectionMatrix = projectionMatrix; + camera->viewMatrix = viewMatrix; } // Copies the viewport (port) properties and enabled flag from parsed room data. diff --git a/src/runner.h b/src/runner.h index 9a815048..e91fc7f1 100644 --- a/src/runner.h +++ b/src/runner.h @@ -156,8 +156,8 @@ typedef struct { int32_t speedY; int32_t objectId; // follow target (object index), -1 = none float viewAngle; - Matrix4f ViewMatrix; - Matrix4f ProjectionMatrix; + Matrix4f viewMatrix; + Matrix4f projectionMatrix; } GMLCamera; typedef struct { diff --git a/src/vm_builtins.c b/src/vm_builtins.c index c53fc114..e2ff9aa6 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -217,23 +217,23 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } -static void UpdateCameraViewSimple(GMLCamera* camera) { +static void updateCameraViewSimple(GMLCamera* camera) { float x = camera->viewX + camera->viewWidth/2; float y = camera->viewY + camera->viewHeight/2; - Matrix4f ViewMatrix; - Matrix4f_identity(&ViewMatrix); - Matrix4f_LookAt(&ViewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&ViewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&ViewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&ViewMatrix, -x, -y, 0.0f); - - Matrix4f ProjectionMatrix; - Matrix4f_Orthographic(&ProjectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); + Matrix4f viewMatrix; + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&viewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); + + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - camera->ViewMatrix = ViewMatrix; - camera->ProjectionMatrix = ProjectionMatrix; + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; } @@ -3546,7 +3546,7 @@ static RValue builtin_camera_set_view_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - camera->ViewMatrix = m; + camera->viewMatrix = m; return RValue_makeUndefined(); } @@ -3554,14 +3554,14 @@ static RValue builtin_camera_get_view_mat(VMContext* ctx, RValue* args, int32_t Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(&camera->ViewMatrix)); + return RValue_makeArray(matrixToGml(&camera->viewMatrix)); } static RValue builtin_camera_get_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(&camera->ProjectionMatrix)); + return RValue_makeArray(matrixToGml(&camera->projectionMatrix)); } static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { @@ -3571,8 +3571,8 @@ static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t if (camera == nullptr || !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); Matrix4f m; matrixFromGml(&m, args[1].array); - camera->ProjectionMatrix = m; - camera->ProjectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; + camera->projectionMatrix = m; + camera->projectionMatrix.m[Matrix_getIndex(1, 1)] = -m.m[Matrix_getIndex(1, 1)]; return RValue_makeUndefined(); } @@ -3769,7 +3769,7 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { - runner->renderer->vtable->applyProjection(runner->renderer, &camera->ViewMatrix, &camera->ProjectionMatrix); + runner->renderer->vtable->applyProjection(runner->renderer, &camera->viewMatrix, &camera->projectionMatrix); runner->renderer->CameraCurrent = RValue_toInt32(args[0]); } return RValue_makeUndefined(); From 767202e4ccbc76441ba13a499bd03daaa84ef91b Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 29 Jun 2026 17:43:16 +0200 Subject: [PATCH 20/22] am I done already... --- src/runner.c | 21 +++++++++++++++++++++ src/runner.h | 3 +++ src/vm_builtins.c | 39 +++++++++------------------------------ 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/runner.c b/src/runner.c index 80ecd54a..1b892b5a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -46,6 +46,26 @@ static void freeRuntimeLayersArray(RuntimeLayer** runtimeLayerArray) { *runtimeLayerArray = nullptr; } +void Runner_updateCameraViewSimple(GMLCamera* camera) { + + float x = camera->viewX + camera->viewWidth/2; + float y = camera->viewY + camera->viewHeight/2; + Matrix4f viewMatrix; + Matrix4f_identity(&viewMatrix); + Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); + Matrix4f_translate(&viewMatrix, x, y, 0.0f); + Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); + Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); + + Matrix4f projectionMatrix; + Matrix4f_Orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); + + + camera->viewMatrix = viewMatrix; + camera->projectionMatrix = projectionMatrix; + +} + // ===[ Helper: Find event action in object hierarchy ]=== // Resolves the handler for (objectIndex, eventType, eventSubtype) via the precomputed ResolvedEventTable. // Returns the CODE chunk handler id, or -1 if the object does not respond. @@ -3253,6 +3273,7 @@ static void updateViews(Runner* runner) { int32_t iy = (int32_t) GMLReal_floor(target->y); camera->viewX = followAxis(camera->viewX, camera->viewWidth, ix, camera->borderX, camera->speedX, (int32_t) room->width); camera->viewY = followAxis(camera->viewY, camera->viewHeight, iy, camera->borderY, camera->speedY, (int32_t) room->height); + Runner_updateCameraViewSimple(camera); } } } diff --git a/src/runner.h b/src/runner.h index e91fc7f1..4ad957c5 100644 --- a/src/runner.h +++ b/src/runner.h @@ -674,6 +674,9 @@ void Runner_removeInstanceFromObjectLists(Runner* runner, Instance* inst); // Reset every per-object list to length 0 without releasing the backing arrays. void Runner_clearAllObjectLists(Runner* runner); +// Update The Camera For Basic Views! +void Runner_updateCameraViewSimple(GMLCamera* camera); + // Push a snapshot of instancesByObject[targetObjIndex] onto runner->instanceSnapshots. Returns the base offset where this snapshot begins. // The length is arrlen(runner->instanceSnapshots) - base. // Invalid indices or empty buckets push zero entries (base == current arena length). diff --git a/src/vm_builtins.c b/src/vm_builtins.c index e2ff9aa6..d1d232cb 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -217,27 +217,6 @@ static DsStack* dsStackGet(Runner* runner, int32_t id) { return &runner->dsStackPool[id]; } -static void updateCameraViewSimple(GMLCamera* camera) { - - float x = camera->viewX + camera->viewWidth/2; - float y = camera->viewY + camera->viewHeight/2; - Matrix4f viewMatrix; - Matrix4f_identity(&viewMatrix); - Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - Matrix4f_translate(&viewMatrix, x, y, 0.0f); - Matrix4f_rotateZ(&viewMatrix, -camera->viewAngle * (float) M_PI / 180.0f); - Matrix4f_translate(&viewMatrix, -x, -y, 0.0f); - - Matrix4f projectionMatrix; - Matrix4f_Orthographic(&projectionMatrix, (float) camera->viewWidth, -((float) camera->viewHeight), 32000.0, 0.0); - - - camera->viewMatrix = viewMatrix; - camera->projectionMatrix = projectionMatrix; - -} - - // ===[ BUILT-IN VARIABLE GET/SET ]=== static bool isValidAlarmIndex(int alarmIndex) { @@ -1590,7 +1569,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewX = RValue_toReal(val); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return; } @@ -1598,7 +1577,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewY = RValue_toInt32(val); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return; } @@ -1606,7 +1585,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewWidth = RValue_toInt32(val); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return; } @@ -1614,7 +1593,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewHeight = RValue_toInt32(val); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return; } @@ -1643,7 +1622,7 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(val); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return; } @@ -3533,7 +3512,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3626,7 +3605,7 @@ static RValue builtin_camera_set_view_size(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewWidth = RValue_toInt32(args[1]); camera->viewHeight = RValue_toInt32(args[2]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3649,7 +3628,7 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (camera != nullptr) { camera->viewAngle = (float) RValue_toReal(args[1]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3715,7 +3694,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - UpdateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); return RValue_makeReal(id); } From 7da4ced54576eef3462f10911f453642d1291ed4 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:15:58 +0200 Subject: [PATCH 21/22] fix merge conflicts --- src/gl/gl_renderer.c | 50 ++++++++++++++++++++------------------------ src/vm_builtins.c | 6 +++--- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index 025066a2..f051a9b9 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -303,13 +303,9 @@ static void glInit(Renderer* renderer, DataWin* dataWin) { GLRenderer* gl = (GLRenderer*) renderer; renderer->dataWin = dataWin; - Matrix4f World; - Matrix4f_identity(&World); - renderer->gmlMatrices[MATRIX_WORLD] = World; - - Matrix4f World; - Matrix4f_identity(&World); - renderer->gmlMatrices[MATRIX_WORLD] = World; + Matrix4f world; + Matrix4f_identity(&world); + renderer->gmlMatrices[MATRIX_WORLD] = world; GMLShader* defaultShader = (GMLShader*)safeCalloc(1, sizeof(GMLShader)); const char* versionStr = (const char*) glGetString(GL_VERSION); @@ -617,20 +613,20 @@ static void glApplyProjection(Renderer* renderer, const Matrix4f* viewMatrix,con // Flush first so pending quads draw under the projection they were issued with. flushBatch(gl); - Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = *viewMatrix; - Matrix4f Projection = *projectionMatrix; + Matrix4f world = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f view = *viewMatrix; + Matrix4f projection = *projectionMatrix; - Matrix4f WorldView; - Matrix4f_multiply(&WorldView, &View, &World); + Matrix4f worldView; + Matrix4f_multiply(&worldView, &view, &world); - Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); + Matrix4f worldViewProjection; + Matrix4f_multiply(&worldViewProjection, &projection, &worldView); - renderer->gmlMatrices[MATRIX_VIEW] = View; - renderer->gmlMatrices[MATRIX_PROJECTION] = Projection; - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + renderer->gmlMatrices[MATRIX_VIEW] = view; + renderer->gmlMatrices[MATRIX_PROJECTION] = projection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = worldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = worldViewProjection; //oh my I hope it's good enough. glShaderSettingsRefresh(renderer); } @@ -2822,18 +2818,18 @@ static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) renderer->gmlMatrices[MatrixType] = Matrix; //yeah just recalculate everything when we change a matrix //TODO LATR: only allow these 3 to be changed directly, other ones should only be allowed to be calculated by the rest of the function - Matrix4f World = renderer->gmlMatrices[MATRIX_WORLD]; - Matrix4f View = renderer->gmlMatrices[MATRIX_VIEW]; - Matrix4f Projection = renderer->gmlMatrices[MATRIX_PROJECTION]; + Matrix4f world = renderer->gmlMatrices[MATRIX_WORLD]; + Matrix4f view = renderer->gmlMatrices[MATRIX_VIEW]; + Matrix4f projection = renderer->gmlMatrices[MATRIX_PROJECTION]; - Matrix4f WorldView; - Matrix4f_multiply(&WorldView, &View, &World); + Matrix4f worldView; + Matrix4f_multiply(&worldView, &view, &world); - Matrix4f WorldViewProjection; - Matrix4f_multiply(&WorldViewProjection, &Projection, &WorldView); + Matrix4f worldViewProjection; + Matrix4f_multiply(&worldViewProjection, &projection, &worldView); - renderer->gmlMatrices[MATRIX_WORLD_VIEW] = WorldView; - renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = WorldViewProjection; + renderer->gmlMatrices[MATRIX_WORLD_VIEW] = worldView; + renderer->gmlMatrices[MATRIX_WORLD_VIEW_PROJECTION] = worldViewProjection; glShaderSettingsRefresh(renderer); diff --git a/src/vm_builtins.c b/src/vm_builtins.c index d1d232cb..f7f241c1 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2968,7 +2968,7 @@ static RValue builtin_matrix_get(MAYBE_UNUSED VMContext *ctx, RValue *args, int3 if (toPrevMatrix && !rvalueIsMatrix(args[1])) return RValue_makeUndefined(); if (!toPrevMatrix) { - return RValue_makeArray(matrixToGml(&ctx->runner->renderer->gmlMatrices[Matrix])); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &ctx->runner->renderer->gmlMatrices[Matrix])); } else { repeat (16, i) { *GMLArray_slot(destArray, i) = RValue_makeReal(ctx->runner->renderer->gmlMatrices[Matrix].m[i]); @@ -3533,14 +3533,14 @@ static RValue builtin_camera_get_view_mat(VMContext* ctx, RValue* args, int32_t Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(&camera->viewMatrix)); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->viewMatrix)); } static RValue builtin_camera_get_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera == nullptr) return RValue_makeUndefined(); - return RValue_makeArray(matrixToGml(&camera->projectionMatrix)); + return RValue_makeArray(matrixToGml(ctx->dataWin->gen8.wadVersion, &camera->projectionMatrix)); } static RValue builtin_camera_set_proj_mat(VMContext* ctx, RValue* args, int32_t argCount) { From 799c93fb19a770f306a48a12ae0544a1018c6398 Mon Sep 17 00:00:00 2001 From: Classic0306 <190026317+Classic0306@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:58:24 +0200 Subject: [PATCH 22/22] did I finally do it correctly? --- src/gl/gl_renderer.c | 52 ++++++++++++++++++++++---------------------- src/renderer.h | 4 ++-- src/runner.c | 8 +++---- src/vm_builtins.c | 38 +++++++++++++++----------------- 4 files changed, 50 insertions(+), 52 deletions(-) diff --git a/src/gl/gl_renderer.c b/src/gl/gl_renderer.c index f051a9b9..c64fa4c2 100644 --- a/src/gl/gl_renderer.c +++ b/src/gl/gl_renderer.c @@ -553,14 +553,14 @@ static void glGpuSetShader(Renderer* renderer, int32_t shaderIndex) { GLShaderUniform* gmAlphaTestEnabledUniform = findShaderUniformByName(gmlShader, "gm_AlphaTestEnabled"); GLShaderUniform* gmAlphaRefValue = findShaderUniformByName(gmlShader, "gm_AlphaRefValue"); - Matrix4f FlippedClip[MATRICES_MAX]; - for (int32_t i = 0; i < MATRICES_MAX; i++) { - FlippedClip[i] = renderer->gmlMatrices[i]; - Matrix4f_flipClipY(&FlippedClip[i]); - } + Matrix4f flippedClip[MATRICES_MAX]; + for (int32_t i = 0; i < MATRICES_MAX; i++) { + flippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&flippedClip[i]); + } if (gmMatricesUniform != nullptr) { - glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, FlippedClip[0].m); + glUniformMatrix4fv(gmMatricesUniform->location, 5, GL_FALSE, flippedClip[0].m); } if (gmFogColourUniform != nullptr) { glUniform1i(gmFogColourUniform->location, gl->fogColor); @@ -592,13 +592,13 @@ static void glShaderSettingsRefresh(Renderer* renderer) { GLShaderUniform* uAlphaTestRef = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestRef"); GLShaderUniform* uAlphaTestEnabled = findShaderUniformByName(gl->defaultShaderProgram, "uAlphaTestEnabled"); GLShaderUniform* uTexture = findShaderUniformByName(gl->defaultShaderProgram, "uTexture"); - Matrix4f FlippedClip[MATRICES_MAX]; + Matrix4f flippedClip[MATRICES_MAX]; for (int32_t i = 0; i < MATRICES_MAX; i++) { - FlippedClip[i] = renderer->gmlMatrices[i]; - Matrix4f_flipClipY(&FlippedClip[i]); + flippedClip[i] = renderer->gmlMatrices[i]; + Matrix4f_flipClipY(&flippedClip[i]); } - glUniformMatrix4fv(uWorldViewProjection->location, 1, GL_FALSE, FlippedClip[MATRIX_WORLD_VIEW_PROJECTION].m); + glUniformMatrix4fv(uWorldViewProjection->location, 1, GL_FALSE, flippedClip[MATRIX_WORLD_VIEW_PROJECTION].m); glUniform4f(uFogColor->location, fogR, fogG, fogB, gl->fogEnable ? 1.0f : 0.0f); glUniform1f(uAlphaTestRef->location, gl->alphaTestRef); glUniform1i(uAlphaTestEnabled->location, gl->alphaTestEnable); @@ -724,13 +724,13 @@ static void glBeginView(Renderer* renderer, MAYBE_UNUSED int32_t viewX, MAYBE_UN glEnable(GL_SCISSOR_TEST); glScissor(portX, portY, portW, portH); - int32_t ViewCurrent = 0; + int32_t viewCurrent = 0; if (renderer->runner->viewsEnabled) { - ViewCurrent = renderer->runner->viewCurrent; + viewCurrent = renderer->runner->viewCurrent; } - RuntimeView* view = &renderer->runner->views[ViewCurrent]; - gl->base.CameraCurrent = view->cameraId; - GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); + RuntimeView* view = &renderer->runner->views[viewCurrent]; + gl->base.cameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.cameraCurrent); glApplyProjection(renderer,&camera->viewMatrix,&camera->projectionMatrix); glShaderSettingsRefresh(renderer); @@ -767,7 +767,7 @@ static void glBeginGUI(Renderer* renderer, MAYBE_UNUSED int32_t guiW, MAYBE_UNUS glEnable(GL_SCISSOR_TEST); //I dunno hopefully this is at least somewhat correct... - gl->base.CameraCurrent = GUI_CAMERA; + gl->base.cameraCurrent = GUI_CAMERA; GMLCamera* camera = &renderer->runner->guiCamera; camera->allocated = true; camera->viewX = 0.0; @@ -804,7 +804,7 @@ static void glSetGuiProjection(Renderer* renderer, int32_t guiW, int32_t guiH, M flushBatch(gl); // GL surfaces are stored bottom-up and draw_surface samples them with vertical flip. - gl->base.CameraCurrent = GUI_CAMERA; + gl->base.cameraCurrent = GUI_CAMERA; GMLCamera* camera = &renderer->runner->guiCamera; camera->allocated = true; camera->viewX = 0.0; @@ -2230,13 +2230,13 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); - int32_t ViewCurrent = 0; + int32_t viewCurrent = 0; if (renderer->runner->viewsEnabled) { - ViewCurrent = renderer->runner->viewCurrent; + viewCurrent = renderer->runner->viewCurrent; } - RuntimeView* view = &renderer->runner->views[ViewCurrent]; - gl->base.CameraCurrent = view->cameraId; - GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.CameraCurrent); + RuntimeView* view = &renderer->runner->views[viewCurrent]; + gl->base.cameraCurrent = view->cameraId; + GMLCamera* camera = Runner_getCameraById(renderer->runner, gl->base.cameraCurrent); if (0 > surfaceId || (uint32_t) surfaceId >= gl->surfaceCount) return false; if (gl->surfaces[surfaceId] == 0) return false; @@ -2269,7 +2269,7 @@ static bool glSetRenderTarget(Renderer* renderer, int32_t surfaceId, bool implic float y = (float) gl->surfaceHeight[surfaceId] * 0.5f; Matrix4f_identity(&viewMatrix); Matrix4f_LookAt(&viewMatrix, x, y, -16000.0, x, y, 16000.0, 0.0, 1.0, 0.0); - gl->base.CameraCurrent = SURFACE_CAMERA; + gl->base.cameraCurrent = SURFACE_CAMERA; GMLCamera* camera = &renderer->runner->surfaceCamera; @@ -2812,10 +2812,10 @@ static bool glShadersSupported(void) { return true; } -static void glSetMatrix(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix) { +static void glSetMatrix(Renderer* renderer, int32_t matrixType, Matrix4f matrix) { GLRenderer* gl = (GLRenderer*) renderer; flushBatch(gl); - renderer->gmlMatrices[MatrixType] = Matrix; + renderer->gmlMatrices[matrixType] = matrix; //yeah just recalculate everything when we change a matrix //TODO LATR: only allow these 3 to be changed directly, other ones should only be allowed to be calculated by the rest of the function Matrix4f world = renderer->gmlMatrices[MATRIX_WORLD]; @@ -2916,6 +2916,6 @@ Renderer* GLRenderer_create(void) { gl->base.drawValign = 0; gl->base.circlePrecision = 24; gl->base.currentShader = -1; - gl->base.CameraCurrent = 0; + gl->base.cameraCurrent = 0; return (Renderer*) gl; } diff --git a/src/renderer.h b/src/renderer.h index 24270024..b9205a5b 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -153,7 +153,7 @@ typedef struct { void (*textureSetStage)(Renderer* renderer, int32_t slot, uint32_t texID); bool (*shaderIsCompiled)(Renderer* renderer, int32_t shader); bool (*shadersSupported)(void); - void (*setMatrix)(Renderer* renderer, int32_t MatrixType, Matrix4f Matrix); + void (*setMatrix)(Renderer* renderer, int32_t matrixType, Matrix4f matrix); } RendererVtable; // ===[ Renderer Base Struct ]=== @@ -176,7 +176,7 @@ struct Renderer { Runner* runner; Matrix4f gmlMatrices[MATRICES_MAX]; int32_t currentShader; - int32_t CameraCurrent; + int32_t cameraCurrent; }; // ===[ Shared Helpers (platform-agnostic) ]=== diff --git a/src/runner.c b/src/runner.c index 1b892b5a..cb72f4b1 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1166,7 +1166,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; runner->renderer->vtable->applyProjection(runner->renderer, &viewMatrix, &projectionMatrix); @@ -1190,7 +1190,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh float viewAngle = camera->viewAngle; runner->viewCurrent = (int32_t) vi; - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; renderer->vtable->beginView(renderer, viewX, viewY, viewW, viewH, portX, portY, portW, portH, viewAngle); Runner_draw(runner); @@ -1206,7 +1206,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh if (!anyViewRendered) { runner->viewCurrent = 0; GMLCamera* camera = Runner_getCameraForView(runner, (int32_t) runner->viewCurrent); - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; // See GameMaker-HTML5's "DrawViews", in specific the !m_enableviews path // When views aren't used, the room width/height is used int32_t viewX, viewY, viewW, viewH; @@ -1245,7 +1245,7 @@ void Runner_drawViews(Runner* runner, int32_t gameW, int32_t gameH, bool debugSh // Reset view_current to 0 so non-Draw events (Step, Alarm, Create) see view_current = 0 runner->viewCurrent = 0; - runner->renderer->CameraCurrent = runner->views[runner->viewCurrent].cameraId; + runner->renderer->cameraCurrent = runner->views[runner->viewCurrent].cameraId; } // ===[ Instance Creation Helper ]=== diff --git a/src/vm_builtins.c b/src/vm_builtins.c index f7f241c1..9bda5a16 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -1568,32 +1568,32 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId case BUILTIN_VAR_VIEW_XVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewX = RValue_toReal(val); - Runner_updateCameraViewSimple(camera); + camera->viewX = RValue_toReal(val); + Runner_updateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_YVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewY = RValue_toInt32(val); - Runner_updateCameraViewSimple(camera); + camera->viewY = RValue_toInt32(val); + Runner_updateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_WVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewWidth = RValue_toInt32(val); - Runner_updateCameraViewSimple(camera); + camera->viewWidth = RValue_toInt32(val); + Runner_updateCameraViewSimple(camera); } return; } case BUILTIN_VAR_VIEW_HVIEW: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewHeight = RValue_toInt32(val); - Runner_updateCameraViewSimple(camera); + camera->viewHeight = RValue_toInt32(val); + Runner_updateCameraViewSimple(camera); } return; } @@ -1621,8 +1621,8 @@ void VMBuiltins_setVariable(VMContext* ctx, Instance* inst, int16_t builtinVarId case BUILTIN_VAR_VIEW_ANGLE: { GMLCamera* camera = Runner_getCameraForView(runner, arrayIndex); if (camera != nullptr) { - camera->viewAngle = (float) RValue_toReal(val); - Runner_updateCameraViewSimple(camera); + camera->viewAngle = (float) RValue_toReal(val); + Runner_updateCameraViewSimple(camera); } return; } @@ -3512,7 +3512,7 @@ static RValue builtin_camera_set_view_pos(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewX = RValue_toReal(args[1]); camera->viewY = RValue_toReal(args[2]); - Runner_updateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3605,7 +3605,7 @@ static RValue builtin_camera_set_view_size(VMContext* ctx, RValue* args, int32_t if (camera != nullptr) { camera->viewWidth = RValue_toInt32(args[1]); camera->viewHeight = RValue_toInt32(args[2]); - Runner_updateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3625,10 +3625,9 @@ static RValue builtin_camera_set_view_angle(VMContext* ctx, RValue* args, int32_ if (2 > argCount) return RValue_makeUndefined(); Runner* runner = ctx->runner; GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); - if (camera != nullptr) - { - camera->viewAngle = (float) RValue_toReal(args[1]); - Runner_updateCameraViewSimple(camera); + if (camera != nullptr) { + camera->viewAngle = (float) RValue_toReal(args[1]); + Runner_updateCameraViewSimple(camera); } return RValue_makeUndefined(); } @@ -3693,8 +3692,7 @@ static RValue builtin_camera_create_view(VMContext* ctx, RValue* args, int32_t a if (argCount > 8) camera->borderX = (uint32_t) RValue_toInt32(args[8]); if (argCount > 9) camera->borderY = (uint32_t) RValue_toInt32(args[9]); - - Runner_updateCameraViewSimple(camera); + Runner_updateCameraViewSimple(camera); return RValue_makeReal(id); } @@ -3730,7 +3728,7 @@ static RValue builtin_view_set_camera(VMContext* ctx, RValue* args, int32_t argC static RValue builtin_camera_get_active(VMContext* ctx, MAYBE_UNUSED RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; if (runner->viewCurrent >= 0 && MAX_VIEWS > runner->viewCurrent) { - return RValue_makeReal(runner->renderer->CameraCurrent); + return RValue_makeReal(runner->renderer->cameraCurrent); } return RValue_makeReal(-1); } @@ -3749,7 +3747,7 @@ static RValue builtin_camera_apply(VMContext* ctx, RValue* args, int32_t argCoun GMLCamera* camera = Runner_getCameraById(runner, RValue_toInt32(args[0])); if (camera != nullptr) { runner->renderer->vtable->applyProjection(runner->renderer, &camera->viewMatrix, &camera->projectionMatrix); - runner->renderer->CameraCurrent = RValue_toInt32(args[0]); + runner->renderer->cameraCurrent = RValue_toInt32(args[0]); } return RValue_makeUndefined(); }