-1

I was following the one lone coder video on rendering to the console and I wrote up the code they were using.

I am unable to get the console to actually show anything but instead upon trying to ctrl + f5 on visual studio, I get the debug window that says "exited with code -1073741819."

this is the code I have so far:

#include <iostream>
#include <Windows.h>
#include <cmath>
#include<chrono>
using namespace std;


int nscreenwidth = 120;
int nscreenheight = 40;
float fPlayerX = 8.0f;
float fPlayerY = 8.0f;
float fPlayerA = 0.0f;

int nMapHeight = 16;
int nMapWidth = 16;
float fFOV = 3.1415 / 4.0;

int main() {
    wchar_t* screen = new wchar_t[nscreenheight * nscreenwidth];
    HANDLE hconsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleActiveScreenBuffer(hconsole);
    DWORD dwBytesWritten = 0;
    wstring map;


    map += L"################";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"#..............#";
    map += L"################";

    auto tp1 = chrono::system_clock::now();
    auto tp2 = chrono::system_clock::now();


    while (1) {
        tp2 = chrono::system_clock::now();
        chrono::duration<float> elapsedtime = tp2 - tp1;
        tp1 = tp2;
        float fElapsedTime = elapsedtime.count();

        if (GetAsyncKeyState((unsigned short)'A') & 0x8000)
            fPlayerA -= (0.1f * fElapsedTime);
        if (GetAsyncKeyState((unsigned short)'D') & 0x8000)
            fPlayerA += (0.1f * fElapsedTime);
        for (int x = 0; x < nscreenwidth; x++) {
            float fDistanceWall = 0;
            float fOffsetfov = (fPlayerA - fFOV / 2.0) + (((float)x / (float)nscreenwidth) * fFOV);
            float fUnitVecX = sinf(fOffsetfov);
            float fUnitVecy = cosf(fOffsetfov);
            bool bHitWall = false;
            while (!bHitWall && fDistanceWall < 16.0) {
                fDistanceWall += 0.1;
                int nTestX = (int)(fPlayerX + (fUnitVecX * fDistanceWall));
                int nTestY = (int)(fPlayerY + (fUnitVecy * fDistanceWall));
                if (nTestX < 0 || nTestX >= nMapWidth || nTestY >= nMapHeight) {
                    bHitWall = true;
                    fDistanceWall = 16.0f;
                }
                else if (map[nTestX * nMapWidth + nTestY] == '#') {
                    bHitWall = true;
                }
            }
            int nCeiling = (float)(nscreenheight / 2.0) - nscreenheight / ((float)fDistanceWall);
            int nFloor = nscreenheight - nCeiling;
            for (int y = 0; y < nscreenheight; y++) {
                if (y > nCeiling) {
                    screen[x * nscreenwidth + y] = ' ';
                }
                else if (y < nFloor) {
                    if(fDistanceWall <= 16.0/4.0)
                        screen[x * nscreenwidth + y] = '#';
                    else if (fDistanceWall < 16.0 / 2.0)
                        screen[x * nscreenwidth + y] = '.';
                    else {
                        screen[x * nscreenwidth + y] = ' ';
                    }
                }
            }
        }


        screen[nscreenheight * nscreenwidth - 1] = '\0';
        WriteConsoleOutputCharacter(hconsole, screen, nscreenwidth * nscreenheight, { 0,0 }, &dwBytesWritten);
    }
    return 0;
} 

I would love to know how to fix this error as I'm super interested as to what's causing it. thank you so much!

  • On an unrelated note, if you make your constants *actual* constants (like e.g. `constexpr unsigned nscreenwidth = 120;`, or possibly `const unsigned nscreenwidth = 120;`) then you can skip the dynamic allocation and instead use a plain array for `screen`. Making constants actually be constant is a good idea anyway. – Some programmer dude Mar 13 '23 at 20:09
  • As for your problem, you have a *crash*. And you need to use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to catch the crash, and locate when and where in your code it happens. Also examine the involved variables at the location of the crash. – Some programmer dude Mar 13 '23 at 20:11
  • The first piece of advice is not to press Ctrl+F5 but instead press F5, go into the debugger and find out exactly where your code is crashing. Visual Studio has an excellent debugger, very easy to use, you should start to learn how to do so. – john Mar 13 '23 at 20:11
  • Also unrelated, but there's almost no use for `float` in modern programs. Use `double` instead. – Some programmer dude Mar 13 '23 at 20:12
  • One thing that stands out for me is why there is no test for a negative `nTestY` here `if (nTestX < 0 || nTestX >= nMapWidth || nTestY >= nMapHeight) {`. That looks like an oversight. – john Mar 13 '23 at 20:14
  • 2
    `[x * nscreenwidth + y]` hmm, so if x is 119, and width is 120, you'll be accessing item `119*120` of an array that only has 120*40 items. (that has to be either `x*height` or `y*width`) – teapot418 Mar 13 '23 at 20:32
  • Are you missing line endings when build the `map` string? – Thomas Matthews Mar 13 '23 at 20:51

1 Answers1

1

I tried to run your code and got an exception: write access violation.screen was 0x11102FC120B3152.

enter image description here

int nscreenwidth = 120;
int nscreenheight = 40;
wchar_t* screen = new wchar_t[nscreenheight * nscreenwidth];

However, the size of the screen in the for loop exceeds the defined range.

screen[x * nscreenwidth + y]

I could solve this problem by swapping the data of nscreenwidth and nscreenheight, or you could consider changing the range of the for loop.

for (int x = 0; x < nscreenwidth; x++)
Yujian Yao - MSFT
  • 945
  • 1
  • 3
  • 9