diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..421a6b9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "sh3eb-elf-g++ - Build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}/${fileBasenameNoExtension}", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "C/C++: sh3eb-elf-g++ build active file", + "miDebuggerPath": "/usr/bin/gdb" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..65e1ec0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "makefile.extensionOutputFolder": "./.vscode" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..42ff0d1 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: sh3eb-elf-g++ build active file", + "command": "/usr/local/cross/bin/sh3eb-elf-g++", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/build/example.d b/build/example.d deleted file mode 100644 index 0d95e1f..0000000 --- a/build/example.d +++ /dev/null @@ -1,5 +0,0 @@ -example.o: /home/heath/PrizmSDK-win-0.5.2/projects/example/src/example.c \ - /home/heath/PrizmSDK-win-0.5.2/include/fxcg/display.h \ - /home/heath/PrizmSDK-win-0.5.2/include/fxcg/keyboard.h -/home/heath/PrizmSDK-win-0.5.2/include/fxcg/display.h: -/home/heath/PrizmSDK-win-0.5.2/include/fxcg/keyboard.h: diff --git a/build/example.o b/build/example.o deleted file mode 100644 index 250df16..0000000 Binary files a/build/example.o and /dev/null differ diff --git a/build/generated_lut.d b/build/generated_lut.d deleted file mode 100644 index 19ba158..0000000 --- a/build/generated_lut.d +++ /dev/null @@ -1,2 +0,0 @@ -generated_lut.o: \ - /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/generated_lut.cpp diff --git a/build/generated_lut.o b/build/generated_lut.o deleted file mode 100644 index a3c962d..0000000 Binary files a/build/generated_lut.o and /dev/null differ diff --git a/build/main.d b/build/main.d index 3e1297e..c482d28 100644 --- a/build/main.d +++ b/build/main.d @@ -1,19 +1,19 @@ -main.o: /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/main.cpp \ +main.o: /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/main.c \ /home/heath/PrizmSDK-win-0.5.2/include/fxcg/display.h \ /home/heath/PrizmSDK-win-0.5.2/include/fxcg/keyboard.h \ - /home/heath/PrizmSDK-win-0.5.2/include/fxcg/system.h \ - /home/heath/PrizmSDK-win-0.5.2/include/fxcg/rtc.h \ /home/heath/PrizmSDK-win-0.5.2/include/fxcg/misc.h \ /home/heath/PrizmSDK-win-0.5.2/include/stddef.h \ + /home/heath/PrizmSDK-win-0.5.2/include/fxcg/rtc.h \ + /home/heath/PrizmSDK-win-0.5.2/include/fxcg/system.h \ /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/../generated_lut.cpp \ /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/../track.cpp \ /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/../kartsprites.cpp /home/heath/PrizmSDK-win-0.5.2/include/fxcg/display.h: /home/heath/PrizmSDK-win-0.5.2/include/fxcg/keyboard.h: -/home/heath/PrizmSDK-win-0.5.2/include/fxcg/system.h: -/home/heath/PrizmSDK-win-0.5.2/include/fxcg/rtc.h: /home/heath/PrizmSDK-win-0.5.2/include/fxcg/misc.h: /home/heath/PrizmSDK-win-0.5.2/include/stddef.h: +/home/heath/PrizmSDK-win-0.5.2/include/fxcg/rtc.h: +/home/heath/PrizmSDK-win-0.5.2/include/fxcg/system.h: /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/../generated_lut.cpp: /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/../track.cpp: /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/../kartsprites.cpp: diff --git a/build/main.o b/build/main.o index e82ea4f..396dc9f 100644 Binary files a/build/main.o and b/build/main.o differ diff --git a/build/non_blocking_dma.d b/build/non_blocking_dma.d deleted file mode 100644 index 52c925a..0000000 --- a/build/non_blocking_dma.d +++ /dev/null @@ -1,4 +0,0 @@ -non_blocking_dma.o: \ - /home/heath/PrizmSDK-win-0.5.2/projects/hello-world/src/non_blocking_dma.cpp \ - /home/heath/PrizmSDK-win-0.5.2/include/fxcg/display.h -/home/heath/PrizmSDK-win-0.5.2/include/fxcg/display.h: diff --git a/build/non_blocking_dma.o b/build/non_blocking_dma.o deleted file mode 100644 index 65cee45..0000000 Binary files a/build/non_blocking_dma.o and /dev/null differ diff --git a/hello-world.bin b/hello-world.bin index ee42838..c749718 100755 Binary files a/hello-world.bin and b/hello-world.bin differ diff --git a/hello-world.g3a b/hello-world.g3a index d4c08d8..213879b 100644 Binary files a/hello-world.g3a and b/hello-world.g3a differ diff --git a/src/main.cpp b/src/main.c similarity index 62% rename from src/main.cpp rename to src/main.c index ccabeb4..d3061a1 100644 --- a/src/main.cpp +++ b/src/main.c @@ -1,11 +1,15 @@ #include #include -#include -#include #include +#include +#include #include "../generated_lut.cpp" +#define bool unsigned char +#define true 1 +#define false 0 + #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) < (Y)) ? (Y) : (X)) @@ -39,7 +43,7 @@ float fmod(float a, float b) { unsigned char getTileType(short xPos, short yPos) { __builtin_expect(xPos < 0 || xPos >= trackImageWidth || yPos < 0 || yPos >= trackImageHeight, 0); if (xPos < 0 || xPos >= trackImageWidth || yPos < 0 || yPos >= trackImageHeight) { - return 0; // Grass + return 0; // Grass } else { int xPixel = xPos / precision; int yPixel = yPos / precision; @@ -68,93 +72,85 @@ unsigned short samplePixel(short xPos, short yPos) { } unsigned short getScreenPixel(unsigned short x, unsigned short y) { - // Used to indicate framerate - /* if (x == 0 && y == 0) { + // Used to indicate framerate + /* if (x == 0 && y == 0) { return angle == 0; } */ - x /= WIDTH_DIVIDER; + x /= WIDTH_DIVIDER; - // Temporary for small screen sizes - /* if (y >= LUT_HEIGHT) return false; + // Temporary for small screen sizes + /* if (y >= LUT_HEIGHT) return false; if (x >= LUT_WIDTH) return false; */ - - if (y < horizon + 2) return COLOR_BLACK; - // If both samples are 0 in the Python, the horizon colour is set but that doesn't seem to be needed + if (y < horizon + 2) return COLOR_BLACK; - unsigned short newY; - __builtin_expect(x == (int)(LUT_WIDTH / 2), 0); - if (x < (int)(LUT_WIDTH / 2)) { - newY = distortion_correction[x][y - horizon]; - } else if (x == (int)(LUT_WIDTH / 2)) { - newY = y - 1; - } else { - newY = distortion_correction[(int)(LUT_WIDTH / 2) + ((int)(LUT_WIDTH / 2) - x)][y - horizon]; + // If both samples are 0 in the Python, the horizon colour is set but that doesn't seem to be needed + + unsigned short newY; + __builtin_expect(x == (int)(LUT_WIDTH / 2), 0); + if (x < (int)(LUT_WIDTH / 2)) { + newY = distortion_correction[x][y - horizon]; + } else if (x == (int)(LUT_WIDTH / 2)) { + newY = y - 1; + } else { + newY = distortion_correction[(int)(LUT_WIDTH / 2) + ((int)(LUT_WIDTH / 2) - x)][y - horizon]; + } + + if ((y - horizon) < sixteenBitHeight) { + short index = x + angle; + index = mod(index, (angleWidth * 4)); + unsigned short element = mod(index, angleWidth); + + if (index < angleWidth) { + return samplePixel( + angles16[element][newY - horizon][0], + angles16[element][newY - horizon][1]); + } else if (index < angleWidth * 2) { + // Return 90 degree rotated position + return samplePixel( + angles16[element][newY - horizon][1], + -angles16[element][newY - horizon][0]); + } else if (index < angleWidth * 3) { + // Return 180 degree rotated position + return samplePixel( + -angles16[element][newY - horizon][0], + -angles16[element][newY - horizon][1]); + } else /*if (index < angleWidth * 4)*/ { + // Return 270 degree rotated position + return samplePixel( + -angles16[element][newY - horizon][1], + angles16[element][newY - horizon][0]); } - if ((y - horizon) < sixteenBitHeight) { - short index = x + angle; - index = mod(index, (angleWidth * 4)); - unsigned short element = mod(index, angleWidth); + } else { + // TODO: no duplicated code? - if (index < angleWidth) { - return samplePixel( - angles16[element][newY - horizon][0], - angles16[element][newY - horizon][1] - ); - } else if (index < angleWidth * 2) { - // Return 90 degree rotated position - return samplePixel( - angles16[element][newY - horizon][1], - -angles16[element][newY - horizon][0] - ); - } else if (index < angleWidth * 3) { - // Return 180 degree rotated position - return samplePixel( - -angles16[element][newY - horizon][0], - -angles16[element][newY - horizon][1] - ); - } else /*if (index < angleWidth * 4)*/ { - // Return 270 degree rotated position - return samplePixel( - -angles16[element][newY - horizon][1], - angles16[element][newY - horizon][0] - ); - } - - } else { - // TODO: no duplicated code? + short index = x + angle; + index = mod(index, (angleWidth * 4)); + unsigned short element = mod(index, angleWidth); - short index = x + angle; - index = mod(index, (angleWidth * 4)); - unsigned short element = mod(index, angleWidth); - - if (index < angleWidth) { - return samplePixel( - angles8[element][newY - horizon - sixteenBitHeight][0], - angles8[element][newY - horizon - sixteenBitHeight][1] - ); - } else if (index < angleWidth * 2) { - // Return 90 degree rotated position - return samplePixel( - angles8[element][newY - horizon - sixteenBitHeight][1], - -angles8[element][newY - horizon - sixteenBitHeight][0] - ); - } else if (index < angleWidth * 3) { - // Return 180 degree rotated position - return samplePixel( - -angles8[element][newY - horizon - sixteenBitHeight][0], - -angles8[element][newY - horizon - sixteenBitHeight][1] - ); - } else /*if (index < angleWidth * 4)*/ { - // Return 270 degree rotated position - return samplePixel( - -angles8[element][newY - horizon - sixteenBitHeight][1], - angles8[element][newY - horizon - sixteenBitHeight][0] - ); - } + if (index < angleWidth) { + return samplePixel( + angles8[element][newY - horizon - sixteenBitHeight][0], + angles8[element][newY - horizon - sixteenBitHeight][1]); + } else if (index < angleWidth * 2) { + // Return 90 degree rotated position + return samplePixel( + angles8[element][newY - horizon - sixteenBitHeight][1], + -angles8[element][newY - horizon - sixteenBitHeight][0]); + } else if (index < angleWidth * 3) { + // Return 180 degree rotated position + return samplePixel( + -angles8[element][newY - horizon - sixteenBitHeight][0], + -angles8[element][newY - horizon - sixteenBitHeight][1]); + } else /*if (index < angleWidth * 4)*/ { + // Return 270 degree rotated position + return samplePixel( + -angles8[element][newY - horizon - sixteenBitHeight][1], + angles8[element][newY - horizon - sixteenBitHeight][0]); } + } } color_t* VRAM; @@ -164,43 +160,49 @@ void setPixel(int x, int y, color_t color) { } // From https://www.cemetech.net/forum/viewtopic.php?t=6114&postdays=0&postorder=asc&start=100 -void CopySpriteMasked(const void*datar, int x, int y, int width, int height, int maskcolor) { - color_t* data = (color_t*) datar; - color_t* VRAM2 = (color_t*) VRAM; - VRAM2 += LCD_WIDTH_PX*y + x; - for(int j=y; j> 4 ); + PRGM_GetKey_OS(buffer); + return (buffer[1] & 0x0F) * 10 + ((buffer[2] & 0xF0) >> 4); } // https://stackoverflow.com/a/3689059/4012708 @@ -227,11 +229,11 @@ float cos(int angle) { int keydown(int basic_keycode) { const unsigned short* keyboard_register = (unsigned short*)0xA44B0000; int row, col, word, bit; - row = basic_keycode%10; - col = basic_keycode/10-1; - word = row>>1; - bit = col + 8*(row&1); - return (0 != (keyboard_register[word] & 1<> 1; + bit = col + 8 * (row & 1); + return (0 != (keyboard_register[word] & 1 << bit)); } void cameraBehind(short x, short y, short objectAngle, short distance) { @@ -246,161 +248,205 @@ void fillSky(unsigned short yMin, unsigned short yMax) { setPixel(x, y, 0x867D); } } + Bdisp_PutDisp_DD(); +} + +// https://prizm.cemetech.net/index.php?title=Useful_Routines +void drawLine(int x1, int y1, int x2, int y2, unsigned short color) { + signed char ix; + signed char iy; + + // if x1 == x2 or y1 == y2, then it does not matter what we set here + int delta_x = (x2 > x1 ? (ix = 1, x2 - x1) : (ix = -1, x1 - x2)) << 1; + int delta_y = (y2 > y1 ? (iy = 1, y2 - y1) : (iy = -1, y1 - y2)) << 1; + + setPixel(x1, y1, color); + if (delta_x >= delta_y) { + int error = delta_y - (delta_x >> 1); // error may go below zero + while (x1 != x2) { + if (error >= 0) { + if (error || (ix > 0)) { + y1 += iy; + error -= delta_x; + } // else do nothing + } // else do nothing + x1 += ix; + error += delta_y; + setPixel(x1, y1, color); + } + } else { + int error = delta_x - (delta_y >> 1); // error may go below zero + while (y1 != y2) { + if (error >= 0) { + if (error || (iy > 0)) { + x1 += ix; + error -= delta_y; + } // else do nothing + } // else do nothing + y1 += iy; + error += delta_x; + setPixel(x1, y1, color); + } + } +} + +unsigned short kartX = 3730; +unsigned short kartY = 2300; +signed char kartSteerAnim = 0; +float kartVel = 0; +float kartAngle = 90; +#define kartSpeed 2 + +bool showFPS = false; +bool exeWasPressed = false; + +// For framerate counter +int lastTime; +int frameCount = 0; + +void main_loop() { + // Main game loop + int currentTime = RTC_GetTicks(); + // If 1 second has passed, print framerate + if (currentTime - lastTime >= 128) { + lastTime = currentTime; + + if (showFPS) { + int x = 8; + int y = 0; + + char buffer[17] = "FPS: "; + itoa(frameCount, (unsigned char*)buffer + 5); + + PrintMiniMini(&x, &y, buffer, 0, COLOR_BLACK, 0); + Bdisp_PutDisp_DD_stripe(24, 34); + } + + frameCount = 0; + } + + // Grass or sand = more friction + unsigned char currentTile = getTileType(kartX / scale, kartY / scale); + if (currentTile == 0 || currentTile == 7 || currentTile == 9 || currentTile == 12 || currentTile == 14 || currentTile == 15 || currentTile == 50 || currentTile == 52) { + kartVel *= 0.8; + } else { + kartVel *= 0.9; + } + float oldKartX = kartX; + float oldKartY = kartY; + kartY += kartVel * sin(-kartAngle); + kartX += kartVel * cos(-kartAngle); + unsigned char newTile = getTileType(kartX / scale, kartY / scale); + if (newTile >= 240 && newTile <= 243) { // Barrier + kartX = oldKartX; + kartY = oldKartY; + } + cameraBehind(kartX, kartY, kartAngle, 150); // TODO: calculate this rather than guessing + + // kartVel += kartSpeed; + + // int key = PRGM_GetKey(); + bool leftPressed = keydown(KEY_PRGM_LEFT); + bool rightPressed = keydown(KEY_PRGM_RIGHT); + bool shiftPressed = keydown(KEY_PRGM_SHIFT); + + if (shiftPressed) { + kartVel += kartSpeed; + } + + if (leftPressed && !rightPressed && kartVel > 3) { + kartAngle -= kartVel / 10; + + kartSteerAnim++; + if (kartSteerAnim > 10) { + kartSteerAnim = 10; + } + } else if (rightPressed && !leftPressed && kartVel > 3) { + kartAngle += kartVel / 10; + + kartSteerAnim--; + if (kartSteerAnim < -10) { + kartSteerAnim = -10; + } + } else { + if (kartSteerAnim > 0) { + kartSteerAnim--; + if (kartSteerAnim < 0) { + kartSteerAnim = 0; + } + } else { + kartSteerAnim++; + if (kartSteerAnim > 0) { + kartSteerAnim = 0; + } + } + } + + // Control the distance + /* if (keydown(KEY_PRGM_UP)) { + distance += 2; + } + if (keydown(KEY_PRGM_DOWN)) { + distance -= 2; + } */ + + bool exePressed = keydown(31); + if (exePressed && !exeWasPressed) { + showFPS = !showFPS; + if (!showFPS) { + // Put the sky back + fillSky(24, 34); + Bdisp_PutDisp_DD_stripe(24, 34); + } + } + exeWasPressed = exePressed; + + if (keydown(KEY_PRGM_MENU)) { + // Allow the OS to handle exiting to the menu + int key; + GetKey(&key); + Bdisp_EnableColor(1); + fillSky(0, LCD_HEIGHT_PX); + } + + if (keydown(KEY_PRGM_ACON)) { + PowerOff(1); + fillSky(0, LCD_HEIGHT_PX); + } + + kartAngle = fmod(kartAngle, 360); + + angle = fmod(kartAngle + 45, 360) * angleWidth / 90; + + for (unsigned short x = 0; x < LCD_WIDTH_PX; x += 2) { + // TODO: Plus 2? + for (unsigned short y = horizon + 2; y < LCD_HEIGHT_PX; y += 1) { + unsigned short thing = getScreenPixel(x, y); + setPixel(x, y, thing); + setPixel(x + 1, y, thing); + } + } + + if (kartSteerAnim >= 0) { + CopySpriteMasked(mksprites[kartSteerAnim / 2], (LCD_WIDTH_PX / 2) - 36, 128, 72, 80, 0x4fe0); + } else { + CopySpriteMaskedFlipped(mksprites[-kartSteerAnim / 2], (LCD_WIDTH_PX / 2) - 36, 128, 72, 80, 0x4fe0); + } + + Bdisp_PutDisp_DD_stripe(horizon + 2, LCD_HEIGHT_PX); + + frameCount++; } int main() { - VRAM = (color_t*) GetVRAMAddress(); + VRAM = (color_t*)GetVRAMAddress(); Bdisp_EnableColor(1); fillSky(0, LCD_HEIGHT_PX); - Bdisp_PutDisp_DD(); - - unsigned short kartX = 3730; - unsigned short kartY = 2300; - signed char kartSteerAnim = 0; - float kartVel = 0; - float kartAngle = 90; - #define kartSpeed 2 - - bool showFPS = false; - bool exeWasPressed = false; - - // For framerate counter - int lastTime = RTC_GetTicks(); - int frameCount = 0; + lastTime = RTC_GetTicks(); while (1) { - // Main game loop - int currentTime = RTC_GetTicks(); - // If 1 second has passed, print framerate - if (currentTime - lastTime >= 128) { - lastTime = currentTime; - - if (showFPS) { - int x = 8; - int y = 0; - - char buffer[17] = "FPS: "; - itoa(frameCount, (unsigned char*) buffer + 5); - - PrintMiniMini(&x, &y, buffer, 0, COLOR_BLACK, 0); - Bdisp_PutDisp_DD_stripe(24, 34); - } - - frameCount = 0; - } - - // Grass or sand = more friction - unsigned char currentTile = getTileType(kartX / scale, kartY / scale); - if (currentTile == 0 || currentTile == 7 || currentTile == 9 || currentTile == 12 || currentTile == 14 || currentTile == 15 || currentTile == 50 || currentTile == 52) { - kartVel *= 0.8; - } else { - kartVel *= 0.9; - } - float oldKartX = kartX; - float oldKartY = kartY; - kartY += kartVel * sin(-kartAngle); - kartX += kartVel * cos(-kartAngle); - unsigned char newTile = getTileType(kartX / scale, kartY / scale); - if (newTile >= 240 && newTile <= 243) { // Barrier - kartX = oldKartX; - kartY = oldKartY; - } - cameraBehind(kartX, kartY, kartAngle, 150); // TODO: calculate this rather than guessing - - // kartVel += kartSpeed; - - // int key = PRGM_GetKey(); - bool leftPressed = keydown(KEY_PRGM_LEFT); - bool rightPressed = keydown(KEY_PRGM_RIGHT); - bool shiftPressed = keydown(KEY_PRGM_SHIFT); - - if (shiftPressed) { - kartVel += kartSpeed; - } - - if (leftPressed && !rightPressed && kartVel > 3) { - kartAngle -= kartVel / 10; - - kartSteerAnim++; - if (kartSteerAnim > 10) { - kartSteerAnim = 10; - } - } else if (rightPressed && !leftPressed && kartVel > 3) { - kartAngle += kartVel / 10; - - kartSteerAnim--; - if (kartSteerAnim < -10) { - kartSteerAnim = -10; - } - } else { - if (kartSteerAnim > 0) { - kartSteerAnim--; - if (kartSteerAnim < 0) { - kartSteerAnim = 0; - } - } else { - kartSteerAnim++; - if (kartSteerAnim > 0) { - kartSteerAnim = 0; - } - } - } - - // Control the distance - /* if (keydown(KEY_PRGM_UP)) { - distance += 2; - } - if (keydown(KEY_PRGM_DOWN)) { - distance -= 2; - } */ - - bool exePressed = keydown(31); - if (exePressed && !exeWasPressed) { - showFPS = !showFPS; - if (!showFPS) { - // Put the sky back - fillSky(24, 34); - Bdisp_PutDisp_DD_stripe(24, 34); - } - } - exeWasPressed = exePressed; - - if (keydown(KEY_PRGM_MENU)) { - // Allow the OS to handle exiting to the menu - int key; - GetKey(&key); - Bdisp_EnableColor(1); - fillSky(0, LCD_HEIGHT_PX); - } - - if (keydown(KEY_PRGM_ACON)) { - PowerOff(1); - fillSky(0, LCD_HEIGHT_PX); - } - - kartAngle = fmod(kartAngle, 360); - - angle = fmod(kartAngle + 45, 360) * angleWidth / 90; - - for (unsigned short x = 0; x < LCD_WIDTH_PX; x += 2) { - // TODO: Plus 2? - for (unsigned short y = horizon + 2; y < LCD_HEIGHT_PX; y += 1) { - unsigned short thing = getScreenPixel(x, y); - setPixel(x, y, thing); - setPixel(x + 1, y, thing); - } - } - - if (kartSteerAnim >= 0) { - CopySpriteMasked(mksprites[kartSteerAnim / 2], (LCD_WIDTH_PX / 2) - 36, 128, 72, 80, 0x4fe0); - } else { - CopySpriteMaskedFlipped(mksprites[-kartSteerAnim / 2], (LCD_WIDTH_PX / 2) - 36, 128, 72, 80, 0x4fe0); - } - - Bdisp_PutDisp_DD_stripe(horizon + 2, LCD_HEIGHT_PX); - - frameCount++; + main_loop(); } /* color_t* VRAM = (color_t*)0xA8000000; // emu address of VRAM