Hotfix: Resolve Linux Audio Crash and add procedural sound fallback - v2.1.3

This commit is contained in:
Michael Howard 2026-04-23 19:51:45 -05:00
parent f169322dc0
commit d8f80b9248
7 changed files with 24 additions and 14 deletions

View File

@ -13,9 +13,11 @@ MorriCraft is a high-performance voxel engine built with C++ and Raylib. It feat
## Version History
### v2.1.1 - Interface Isolation (Latest)
* **Menu Collision Fix**: Resolved a state conflict where the Direct Connect menu would draw over the Skin Editor.
* **State Hardening**: Correctly isolated all menu drawing blocks to prevent visual "hijacking" of new interfaces.
### v2.1.3 - Stability & Audio Fallback (Latest)
* **Linux Stability Fix**: Resolved a critical PulseAudio crash caused by double audio device initialization.
* **Procedural Hit Sound**: Implemented a synthesized audio fallback for the hit effect to ensure combat feedback always works.
### v2.1.2 - Combat Update
### v2.1.0 - Personalization & Stability
* **Integrated Skin Editor**: Personalize your shirt and pants colors directly from the Options menu.

Binary file not shown.

View File

@ -1 +1 @@
v2.1.1
v2.1.3

Binary file not shown.

View File

@ -1 +1 @@
v2.1.1
v2.1.3

View File

@ -783,12 +783,24 @@ int main(void)
// By default, windows have minimize, maximize, and close buttons on the top bar.
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
InitWindow(screenWidth, screenHeight, "MorriCraft v2.1.2");
InitWindow(screenWidth, screenHeight, "MorriCraft v2.1.3");
LoadConfig();
SetExitKey(KEY_NULL); // Prevent ESC from closing the window
// Initialize audio device
InitAudioDevice();
hitSound = LoadSound("assets/hit.wav");
if (hitSound.frameCount == 0) {
// Procedural fallback if asset missing
Wave w = { 0 };
w.frameCount = 4410; w.sampleRate = 44100; w.sampleSize = 16; w.channels = 1;
w.data = RL_MALLOC(w.frameCount * 2);
short* d = (short*)w.data;
for(int i=0; i<w.frameCount; i++) d[i] = (short)(sinf(i*0.5f) * 15000 * (1.0f - (float)i/w.frameCount));
hitSound = LoadSoundFromWave(w);
UnloadWave(w);
}
// Load the title image, music, and font
// NOTE: Textures and Fonts MUST be loaded after Window initialization
@ -845,11 +857,7 @@ int main(void)
char targetIP[128] = "127.0.0.1";
char targetPort[16] = "12345";
int activeNetField = 0; // 0=none, 1=IP, 2=Port
InitNetworking();
InitAudioDevice();
hitSound = LoadSound("assets/hit.wav");
if (hitSound.frameCount == 0) TraceLog(LOG_WARNING, "Hit sound NOT LOADED! Make sure assets/hit.wav exists.");
InventorySlot mouseHeldItem(AIR, 0);
@ -1944,8 +1952,8 @@ int main(void)
DrawTexturePro(titleTexture, sourceRec, destRec, origin, 0.0f, WHITE);
EndMode2D();
// Show Version Number (v2.1.2) in Red
DrawTextEx(customFont, "v2.1.2", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED);
// Show Version Number (v2.1.3) in Red
DrawTextEx(customFont, "v2.1.3", (Vector2){ (float)currentWidth - 140, (float)currentHeight - 40 }, 22, 1.0f, RED);
// --- PLAYER NAME POPUP (IF MISSING) ---
if (playerName == "") {
@ -2040,7 +2048,6 @@ int main(void)
Color textColor = isHovered ? (Color){ 255, 255, 160, 255 } : (Color){ 220, 220, 220, 255 };
DrawTextEx(customFont, buttons[i], (Vector2){ (float)textPosX, (float)textPosY }, fontSize, 1.0f, textColor);
}
}
} else if (currentState == LOAD_WORLD_MENU) {
targetZoom = 1.0f;
DrawRectangle(0, 0, currentWidth, currentHeight, (Color){ 0, 0, 0, 180 });
@ -2468,6 +2475,7 @@ int main(void)
activeHotbarSlot = 0;
}
}
}
// Draw Gameplay overlay if we entered gameplay
if (currentState == GAMEPLAY || currentState == PAUSE_MENU || currentState == CRAFTING_GUI) {

View File

@ -1 +1 @@
v2.1.1
v2.1.3