|  | 
|  | 1 | +{ | 
|  | 2 | +  "cells": [ | 
|  | 3 | +    { | 
|  | 4 | +      "cell_type": "code", | 
|  | 5 | +      "execution_count": 1, | 
|  | 6 | +      "id": "72cd5c0c-3a52-43a5-a714-0baee1f7464c", | 
|  | 7 | +      "metadata": { | 
|  | 8 | +        "trusted": true, | 
|  | 9 | +        "vscode": { | 
|  | 10 | +          "languageId": "c++" | 
|  | 11 | +        } | 
|  | 12 | +      }, | 
|  | 13 | +      "outputs": [], | 
|  | 14 | +      "source": [ | 
|  | 15 | +        "// Adapted from smallpt, a Path Tracer by Kevin Beason, 2008\n", | 
|  | 16 | +        "#include <math.h>\n", | 
|  | 17 | +        "#include <stdlib.h>\n", | 
|  | 18 | +        "#include <vector>\n", | 
|  | 19 | +        "\n", | 
|  | 20 | +        "struct Vec {\n", | 
|  | 21 | +        "  double x, y, z; // position, also color (r,g,b)\n", | 
|  | 22 | +        "  Vec(double x_ = 0, double y_ = 0, double z_ = 0) {\n", | 
|  | 23 | +        "    x = x_;\n", | 
|  | 24 | +        "    y = y_;\n", | 
|  | 25 | +        "    z = z_;\n", | 
|  | 26 | +        "  }\n", | 
|  | 27 | +        "  Vec operator+(const Vec &b) const { return Vec(x + b.x, y + b.y, z + b.z); }\n", | 
|  | 28 | +        "  Vec operator-(const Vec &b) const { return Vec(x - b.x, y - b.y, z - b.z); }\n", | 
|  | 29 | +        "  Vec operator*(double b) const { return Vec(x * b, y * b, z * b); }\n", | 
|  | 30 | +        "  Vec mult(const Vec &b) const { return Vec(x * b.x, y * b.y, z * b.z); }\n", | 
|  | 31 | +        "  Vec &norm() { return *this = *this * (1 / sqrt(x * x + y * y + z * z)); }\n", | 
|  | 32 | +        "  double dot(const Vec &b) const { return x * b.x + y * b.y + z * b.z; }\n", | 
|  | 33 | +        "  Vec operator%(Vec &b) { // cross\n", | 
|  | 34 | +        "    return Vec(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);\n", | 
|  | 35 | +        "  }\n", | 
|  | 36 | +        "};\n", | 
|  | 37 | +        "struct Ray {\n", | 
|  | 38 | +        "  Vec o, d;\n", | 
|  | 39 | +        "  Ray(Vec o_, Vec d_) : o(o_), d(d_) {}\n", | 
|  | 40 | +        "};\n", | 
|  | 41 | +        "enum Refl_t { DIFF, SPEC, REFR }; // material types, used in radiance()\n", | 
|  | 42 | +        "struct Sphere {\n", | 
|  | 43 | +        "  double rad;  // radius\n", | 
|  | 44 | +        "  Vec p, e, c; // position, emission, color\n", | 
|  | 45 | +        "  Refl_t refl; // reflection type (DIFFuse, SPECular, REFRactive)\n", | 
|  | 46 | +        "  Sphere(double rad_, Vec p_, Vec e_, Vec c_, Refl_t refl_)\n", | 
|  | 47 | +        "      : rad(rad_), p(p_), e(e_), c(c_), refl(refl_) {}\n", | 
|  | 48 | +        "  double intersect(const Ray &r) const { // returns distance, 0 if nohit\n", | 
|  | 49 | +        "    Vec op = p - r.o; // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0\n", | 
|  | 50 | +        "    double t, eps = 1e-4, b = op.dot(r.d), det = b * b - op.dot(op) + rad * rad;\n", | 
|  | 51 | +        "    if (det < 0)\n", | 
|  | 52 | +        "      return 0;\n", | 
|  | 53 | +        "    else\n", | 
|  | 54 | +        "      det = sqrt(det);\n", | 
|  | 55 | +        "    return (t = b - det) > eps ? t : ((t = b + det) > eps ? t : 0);\n", | 
|  | 56 | +        "  }\n", | 
|  | 57 | +        "};" | 
|  | 58 | +      ] | 
|  | 59 | +    }, | 
|  | 60 | +    { | 
|  | 61 | +      "cell_type": "code", | 
|  | 62 | +      "execution_count": 2, | 
|  | 63 | +      "id": "acc1ec30-5f0a-446f-a066-3dc3369ed39e", | 
|  | 64 | +      "metadata": { | 
|  | 65 | +        "trusted": true, | 
|  | 66 | +        "vscode": { | 
|  | 67 | +          "languageId": "c++" | 
|  | 68 | +        } | 
|  | 69 | +      }, | 
|  | 70 | +      "outputs": [], | 
|  | 71 | +      "source": [ | 
|  | 72 | +        "std::vector<Sphere> spheres = {\n", | 
|  | 73 | +        "    // Scene: radius, position, emission, color, material\n", | 
|  | 74 | +        "    Sphere(1e5, Vec(1e5 + 1, 40.8, 81.6), Vec(), Vec(.75, .25, .25),\n", | 
|  | 75 | +        "           DIFF), // Left\n", | 
|  | 76 | +        "    Sphere(1e5, Vec(-1e5 + 99, 40.8, 81.6), Vec(), Vec(.25, .25, .75),\n", | 
|  | 77 | +        "           DIFF),                                                     // Rght\n", | 
|  | 78 | +        "    Sphere(1e5, Vec(50, 40.8, 1e5), Vec(), Vec(.75, .75, .75), DIFF), // Back\n", | 
|  | 79 | +        "    Sphere(1e5, Vec(50, 40.8, -1e5 + 170), Vec(), Vec(), DIFF),       // Frnt\n", | 
|  | 80 | +        "    Sphere(1e5, Vec(50, 1e5, 81.6), Vec(), Vec(.75, .75, .75), DIFF), // Botm\n", | 
|  | 81 | +        "    Sphere(1e5, Vec(50, -1e5 + 81.6, 81.6), Vec(), Vec(.75, .75, .75),\n", | 
|  | 82 | +        "           DIFF),                                                      // Top\n", | 
|  | 83 | +        "    Sphere(16.5, Vec(27, 16.5, 47), Vec(), Vec(1, 1, 1) * .999, SPEC), // Mirr\n", | 
|  | 84 | +        "    Sphere(16.5, Vec(73, 16.5, 78), Vec(), Vec(1, 1, 1) * .999, REFR), // Glas\n", | 
|  | 85 | +        "    Sphere(600, Vec(50, 681.6 - .27, 81.6), Vec(12, 12, 12), Vec(),\n", | 
|  | 86 | +        "           DIFF) // Lite\n", | 
|  | 87 | +        "};\n", | 
|  | 88 | +        "\n", | 
|  | 89 | +        "inline double clamp(double x) { return x < 0 ? 0 : x > 1 ? 1 : x; }\n", | 
|  | 90 | +        "inline int toInt(double x) { return int(pow(clamp(x), 1 / 2.2) * 255 + .5); }\n", | 
|  | 91 | +        "inline bool intersect(const Ray &r, double &t, int &id) {\n", | 
|  | 92 | +        "  double n = spheres.size(), d, inf = t = 1e20;\n", | 
|  | 93 | +        "  for (int i = int(n); i--;)\n", | 
|  | 94 | +        "    if ((d = spheres[i].intersect(r)) && d < t) {\n", | 
|  | 95 | +        "      t = d;\n", | 
|  | 96 | +        "      id = i;\n", | 
|  | 97 | +        "    }\n", | 
|  | 98 | +        "  return t < inf;\n", | 
|  | 99 | +        "}\n" | 
|  | 100 | +      ] | 
|  | 101 | +    }, | 
|  | 102 | +    { | 
|  | 103 | +      "cell_type": "code", | 
|  | 104 | +      "execution_count": 3, | 
|  | 105 | +      "id": "cf0fd047-c5da-4606-aeae-4358d2064f10", | 
|  | 106 | +      "metadata": { | 
|  | 107 | +        "trusted": true, | 
|  | 108 | +        "vscode": { | 
|  | 109 | +          "languageId": "c++" | 
|  | 110 | +        } | 
|  | 111 | +      }, | 
|  | 112 | +      "outputs": [], | 
|  | 113 | +      "source": [ | 
|  | 114 | +        "Vec radiance(const Ray &r, int depth, unsigned short *Xi) {\n", | 
|  | 115 | +        "  double t;   // distance to intersection\n", | 
|  | 116 | +        "  int id = 0; // id of intersected object\n", | 
|  | 117 | +        "  if (!intersect(r, t, id))\n", | 
|  | 118 | +        "    return Vec();                  // if miss, return black\n", | 
|  | 119 | +        "  const Sphere &obj = spheres[id]; // the hit object\n", | 
|  | 120 | +        "  Vec x = r.o + r.d * t, n = (x - obj.p).norm(),\n", | 
|  | 121 | +        "      nl = n.dot(r.d) < 0 ? n : n * -1, f = obj.c;\n", | 
|  | 122 | +        "  double p = f.x > f.y && f.x > f.z ? f.x : f.y > f.z ? f.y : f.z; // max refl\n", | 
|  | 123 | +        "  if (++depth > 5) {\n", | 
|  | 124 | +        "    if (erand48(Xi) < p) {\n", | 
|  | 125 | +        "      f = f * (1 / p);\n", | 
|  | 126 | +        "    } else {\n", | 
|  | 127 | +        "      return obj.e; // R.R.\n", | 
|  | 128 | +        "    }\n", | 
|  | 129 | +        "  }\n", | 
|  | 130 | +        "  if (obj.refl == DIFF) { // Ideal DIFFUSE reflection\n", | 
|  | 131 | +        "    double r1 = 2 * M_PI * erand48(Xi), r2 = erand48(Xi), r2s = sqrt(r2);\n", | 
|  | 132 | +        "    Vec w = nl, u = ((fabs(w.x) > .1 ? Vec(0, 1) : Vec(1)) % w).norm(),\n", | 
|  | 133 | +        "        v = w % u;\n", | 
|  | 134 | +        "    Vec d = (u * cos(r1) * r2s + v * sin(r1) * r2s + w * sqrt(1 - r2)).norm();\n", | 
|  | 135 | +        "    return obj.e + f.mult(radiance(Ray(x, d), depth, Xi));\n", | 
|  | 136 | +        "  } else if (obj.refl == SPEC) // Ideal SPECULAR reflection\n", | 
|  | 137 | +        "    return obj.e +\n", | 
|  | 138 | +        "           f.mult(radiance(Ray(x, r.d - n * 2 * n.dot(r.d)), depth, Xi));\n", | 
|  | 139 | +        "  Ray reflRay(x, r.d - n * 2 * n.dot(r.d)); // Ideal dielectric REFRACTION\n", | 
|  | 140 | +        "  bool into = n.dot(nl) > 0;                // Ray from outside going in?\n", | 
|  | 141 | +        "  double nc = 1, nt = 1.5, nnt = into ? nc / nt : nt / nc, ddn = r.d.dot(nl),\n", | 
|  | 142 | +        "         cos2t;\n", | 
|  | 143 | +        "  if ((cos2t = 1 - nnt * nnt * (1 - ddn * ddn)) <\n", | 
|  | 144 | +        "      0) // Total internal reflection\n", | 
|  | 145 | +        "    return obj.e + f.mult(radiance(reflRay, depth, Xi));\n", | 
|  | 146 | +        "  Vec tdir =\n", | 
|  | 147 | +        "      (r.d * nnt - n * ((into ? 1 : -1) * (ddn * nnt + sqrt(cos2t)))).norm();\n", | 
|  | 148 | +        "  double a = nt - nc, b = nt + nc, R0 = a * a / (b * b),\n", | 
|  | 149 | +        "         c = 1 - (into ? -ddn : tdir.dot(n));\n", | 
|  | 150 | +        "  double Re = R0 + (1 - R0) * c * c * c * c * c, Tr = 1 - Re, P = .25 + .5 * Re,\n", | 
|  | 151 | +        "         RP = Re / P, TP = Tr / (1 - P);\n", | 
|  | 152 | +        "  return obj.e +\n", | 
|  | 153 | +        "         f.mult(depth > 2\n", | 
|  | 154 | +        "                    ? (erand48(Xi) < P ? // Russian roulette\n", | 
|  | 155 | +        "                           radiance(reflRay, depth, Xi) * RP\n", | 
|  | 156 | +        "                                       : radiance(Ray(x, tdir), depth, Xi) * TP)\n", | 
|  | 157 | +        "                    : radiance(reflRay, depth, Xi) * Re +\n", | 
|  | 158 | +        "                          radiance(Ray(x, tdir), depth, Xi) * Tr);\n", | 
|  | 159 | +        "}" | 
|  | 160 | +      ] | 
|  | 161 | +    }, | 
|  | 162 | +    { | 
|  | 163 | +      "cell_type": "code", | 
|  | 164 | +      "execution_count": 4, | 
|  | 165 | +      "id": "70a01b15-3b76-4008-b674-0cc05b0342dd", | 
|  | 166 | +      "metadata": { | 
|  | 167 | +        "trusted": true, | 
|  | 168 | +        "vscode": { | 
|  | 169 | +          "languageId": "c++" | 
|  | 170 | +        } | 
|  | 171 | +      }, | 
|  | 172 | +      "outputs": [], | 
|  | 173 | +      "source": [ | 
|  | 174 | +        "#include <SDL2/SDL.h>\n", | 
|  | 175 | +        "#include <string>\n", | 
|  | 176 | +        "#include <fstream>\n", | 
|  | 177 | +        "#include <sstream>\n", | 
|  | 178 | +        "#include <iostream>\n", | 
|  | 179 | +        "#include \"nlohmann/json.hpp\"\n", | 
|  | 180 | +        "#include \"xeus/xbase64.hpp\"\n", | 
|  | 181 | +        "#include \"xcpp/xdisplay.hpp\"\n", | 
|  | 182 | +        "\n", | 
|  | 183 | +        "namespace nl = nlohmann;\n", | 
|  | 184 | +        "\n", | 
|  | 185 | +        "namespace im\n", | 
|  | 186 | +        "{\n", | 
|  | 187 | +        "    struct image\n", | 
|  | 188 | +        "    {   \n", | 
|  | 189 | +        "        inline image(const std::string& filename)\n", | 
|  | 190 | +        "        {\n", | 
|  | 191 | +        "            std::ifstream fin(filename, std::ios::binary);   \n", | 
|  | 192 | +        "            m_buffer << fin.rdbuf();\n", | 
|  | 193 | +        "        }\n", | 
|  | 194 | +        "        \n", | 
|  | 195 | +        "        std::stringstream m_buffer;\n", | 
|  | 196 | +        "    };\n", | 
|  | 197 | +        "    \n", | 
|  | 198 | +        "    nl::json mime_bundle_repr(const image& i)\n", | 
|  | 199 | +        "    {\n", | 
|  | 200 | +        "        auto bundle = nl::json::object();\n", | 
|  | 201 | +        "        bundle[\"image/bmp\"] = xeus::base64encode(i.m_buffer.str());\n", | 
|  | 202 | +        "        return bundle;\n", | 
|  | 203 | +        "    }\n", | 
|  | 204 | +        "}\n", | 
|  | 205 | +        "\n", | 
|  | 206 | +        "// Function to save SDL surface as BMP persistently\n", | 
|  | 207 | +        "void save_bmp_to_filesystem(SDL_Surface* surface, const std::string& filename)\n", | 
|  | 208 | +        "{\n", | 
|  | 209 | +        "    if (surface)\n", | 
|  | 210 | +        "    {\n", | 
|  | 211 | +        "        if (SDL_SaveBMP(surface, filename.c_str()) == 0)\n", | 
|  | 212 | +        "        {\n", | 
|  | 213 | +        "            std::cout << \"[DEBUG] Surface saved to \" << filename << std::endl;\n", | 
|  | 214 | +        "        }\n", | 
|  | 215 | +        "        else\n", | 
|  | 216 | +        "        {\n", | 
|  | 217 | +        "            std::cerr << \"[ERROR] Failed to save BMP to \" << filename << \": \" << SDL_GetError() << std::endl;\n", | 
|  | 218 | +        "        }\n", | 
|  | 219 | +        "    }\n", | 
|  | 220 | +        "    else\n", | 
|  | 221 | +        "    {\n", | 
|  | 222 | +        "        std::cerr << \"[ERROR] Surface is null, cannot save BMP.\" << std::endl;\n", | 
|  | 223 | +        "    }\n", | 
|  | 224 | +        "}\n", | 
|  | 225 | +        "\n", | 
|  | 226 | +        "// Function to encode an SDL surface and render it in Jupyter\n", | 
|  | 227 | +        "void render_sdl_surface_to_jupyter(SDL_Surface* surface, const std::string& filename)\n", | 
|  | 228 | +        "{\n", | 
|  | 229 | +        "\n", | 
|  | 230 | +        "    if (!surface)\n", | 
|  | 231 | +        "    {\n", | 
|  | 232 | +        "        std::cerr << \"[ERROR] Surface is null\" << std::endl;\n", | 
|  | 233 | +        "        return;\n", | 
|  | 234 | +        "    }\n", | 
|  | 235 | +        "\n", | 
|  | 236 | +        "    std::cout << \"[DEBUG] Surface created successfully\" << std::endl;\n", | 
|  | 237 | +        "\n", | 
|  | 238 | +        "    im::image output(filename);\n", | 
|  | 239 | +        "    xcpp::display(output);\n", | 
|  | 240 | +        "    \n", | 
|  | 241 | +        "    // Cleanup\n", | 
|  | 242 | +        "    SDL_FreeSurface(surface);\n", | 
|  | 243 | +        "    std::cout << \"[DEBUG] Surface freed\" << std::endl;\n", | 
|  | 244 | +        "    remove(filename.c_str());\n", | 
|  | 245 | +        "}" | 
|  | 246 | +      ] | 
|  | 247 | +    }, | 
|  | 248 | +    { | 
|  | 249 | +      "cell_type": "code", | 
|  | 250 | +      "execution_count": null, | 
|  | 251 | +      "id": "2fd6e42b-6e84-46e5-9197-0e0c2e054ad1", | 
|  | 252 | +      "metadata": { | 
|  | 253 | +        "trusted": true, | 
|  | 254 | +        "vscode": { | 
|  | 255 | +          "languageId": "c++" | 
|  | 256 | +        } | 
|  | 257 | +      }, | 
|  | 258 | +      "outputs": [], | 
|  | 259 | +      "source": [ | 
|  | 260 | +        "int main() {\n", | 
|  | 261 | +        "    // Debug: Initialization\n", | 
|  | 262 | +        "    std::cout << \"[DEBUG] Initializing SDL\" << std::endl;\n", | 
|  | 263 | +        "\n", | 
|  | 264 | +        "    if (SDL_Init(SDL_INIT_EVENTS) != 0) {\n", | 
|  | 265 | +        "        std::cerr << \"[ERROR] SDL_Init failed: \" << SDL_GetError() << std::endl;\n", | 
|  | 266 | +        "        return 1;\n", | 
|  | 267 | +        "    }\n", | 
|  | 268 | +        "    std::cout << \"[DEBUG] SDL initialized successfully\" << std::endl;\n", | 
|  | 269 | +        "\n", | 
|  | 270 | +        "    // Define width, height, and samples\n", | 
|  | 271 | +        "    int w = 320, h = 240, samps = 16; // # samples\n", | 
|  | 272 | +        "    std::cout << \"[DEBUG] Dimensions: \" << w << \"x\" << h << \", Samples: \" << samps << std::endl;\n", | 
|  | 273 | +        "\n", | 
|  | 274 | +        "    // Create an off-screen surface\n", | 
|  | 275 | +        "    SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGBA32);\n", | 
|  | 276 | +        "    if (!surface) {\n", | 
|  | 277 | +        "        std::cerr << \"[ERROR] Failed to create SDL surface: \" << SDL_GetError() << std::endl;\n", | 
|  | 278 | +        "        SDL_Quit();\n", | 
|  | 279 | +        "        return 1;\n", | 
|  | 280 | +        "    }\n", | 
|  | 281 | +        "    std::cout << \"[DEBUG] SDL surface created successfully\" << std::endl;\n", | 
|  | 282 | +        "\n", | 
|  | 283 | +        "    // Prepare the camera and pixel buffer\n", | 
|  | 284 | +        "    Ray cam(Vec(50, 52, 295.6), Vec(0, -0.042612, -1).norm()); // cam pos, dir\n", | 
|  | 285 | +        "    Vec cx = Vec(w * .5135 / h), cy = (cx % cam.d).norm() * .5135, r,\n", | 
|  | 286 | +        "        *c = new Vec[w * h];\n", | 
|  | 287 | +        "\n", | 
|  | 288 | +        "    std::cout << \"[DEBUG] The image should be on your screen soon\" << std::endl;\n", | 
|  | 289 | +        "    // Render the scene\n", | 
|  | 290 | +        "    for (int y = 0; y < h; y++) { // Loop over image rows\n", | 
|  | 291 | +        "        unsigned short x, Xi[3] = {0, 0, static_cast<unsigned short>(y * y * y)};\n", | 
|  | 292 | +        "        for (x = 0; x < w; x++) { // Loop cols\n", | 
|  | 293 | +        "            int sy, i = (h - y - 1) * w + x;\n", | 
|  | 294 | +        "            for (sy = 0; sy < 2; sy++) { // 2x2 subpixel rows\n", | 
|  | 295 | +        "                int sx;\n", | 
|  | 296 | +        "                for (sx = 0; sx < 2; sx++, r = Vec()) { // 2x2 subpixel cols\n", | 
|  | 297 | +        "                    for (int s = 0; s < samps; s++) { // Subpixel sampling\n", | 
|  | 298 | +        "                        double r1 = 2 * erand48(Xi),\n", | 
|  | 299 | +        "                               dx = r1 < 1 ? sqrt(r1) - 1 : 1 - sqrt(2 - r1);\n", | 
|  | 300 | +        "                        double r2 = 2 * erand48(Xi),\n", | 
|  | 301 | +        "                               dy = r2 < 1 ? sqrt(r2) - 1 : 1 - sqrt(2 - r2);\n", | 
|  | 302 | +        "                        Vec d = cx * (((sx + .5 + dx) / 2 + x) / w - .5) +\n", | 
|  | 303 | +        "                                cy * (((sy + .5 + dy) / 2 + y) / h - .5) + cam.d;\n", | 
|  | 304 | +        "                        r = r + radiance(Ray(cam.o + d * 140, d.norm()), 0, Xi) * (1. / samps);\n", | 
|  | 305 | +        "                    }\n", | 
|  | 306 | +        "                    c[i] = c[i] + Vec(clamp(r.x), clamp(r.y), clamp(r.z)) * .25;\n", | 
|  | 307 | +        "                }\n", | 
|  | 308 | +        "            }\n", | 
|  | 309 | +        "        }\n", | 
|  | 310 | +        "    }\n", | 
|  | 311 | +        "\n", | 
|  | 312 | +        "    // Map the pixel buffer to the SDL surface\n", | 
|  | 313 | +        "    uint8_t* pixels = (uint8_t*)surface->pixels;\n", | 
|  | 314 | +        "    for (int i = 0; i < w * h; i++) {\n", | 
|  | 315 | +        "        uint32_t* pixel_ptr = (uint32_t*)pixels + i;\n", | 
|  | 316 | +        "        *pixel_ptr = SDL_MapRGBA(surface->format, \n", | 
|  | 317 | +        "                                 toInt(c[i].x), // Red\n", | 
|  | 318 | +        "                                 toInt(c[i].y), // Green\n", | 
|  | 319 | +        "                                 toInt(c[i].z), // Blue\n", | 
|  | 320 | +        "                                 255);          // Alpha\n", | 
|  | 321 | +        "    }\n", | 
|  | 322 | +        "    std::cout << \"[DEBUG] Mapped pixel buffer to surface\" << std::endl;\n", | 
|  | 323 | +        "\n", | 
|  | 324 | +        "    // Save the BMP to the filesystem\n", | 
|  | 325 | +        "    const std::string bmp_filename = \"render.bmp\";\n", | 
|  | 326 | +        "    save_bmp_to_filesystem(surface, bmp_filename);\n", | 
|  | 327 | +        "\n", | 
|  | 328 | +        "    // Render the surface to Jupyter\n", | 
|  | 329 | +        "    render_sdl_surface_to_jupyter(surface, bmp_filename);\n", | 
|  | 330 | +        "\n", | 
|  | 331 | +        "    // Cleanup\n", | 
|  | 332 | +        "    delete[] c;\n", | 
|  | 333 | +        "    SDL_Quit();\n", | 
|  | 334 | +        "    std::cout << \"[DEBUG] Exiting main\" << std::endl;\n", | 
|  | 335 | +        "\n", | 
|  | 336 | +        "    return 0;\n", | 
|  | 337 | +        "}\n", | 
|  | 338 | +        "\n", | 
|  | 339 | +        "main();" | 
|  | 340 | +      ] | 
|  | 341 | +    } | 
|  | 342 | +  ], | 
|  | 343 | +  "metadata": { | 
|  | 344 | +    "kernelspec": { | 
|  | 345 | +      "display_name": "C++20", | 
|  | 346 | +      "language": "cpp", | 
|  | 347 | +      "name": "xcpp20" | 
|  | 348 | +    }, | 
|  | 349 | +    "language_info": { | 
|  | 350 | +      "codemirror_mode": "text/x-c++src", | 
|  | 351 | +      "file_extension": ".cpp", | 
|  | 352 | +      "mimetype": "text/x-c++src", | 
|  | 353 | +      "name": "C++", | 
|  | 354 | +      "version": "20" | 
|  | 355 | +    } | 
|  | 356 | +  }, | 
|  | 357 | +  "nbformat": 4, | 
|  | 358 | +  "nbformat_minor": 5 | 
|  | 359 | +} | 
0 commit comments