diff --git a/3rdParty/Storm/Source/storm.h b/3rdParty/Storm/Source/storm.h index 05c003350..d84ad409a 100644 --- a/3rdParty/Storm/Source/storm.h +++ b/3rdParty/Storm/Source/storm.h @@ -907,7 +907,7 @@ BOOL STORMAPI STransCreateI(void *pBuffer, int width, int height, int bpp, int a BOOL STORMAPI SVidDestroy(); BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero); BOOL STORMAPI SVidInitialize(HANDLE video); -BOOL STORMAPI SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video); +BOOL STORMAPI SVidPlayBegin(char *filename, int a2, int a3, int a4, int a5, int flags, HANDLE *video); BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3); BOOL STORMAPI SVidPlayEnd(HANDLE video); diff --git a/CMakeLists.txt b/CMakeLists.txt index 60914b08e..c35cb4016 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ add_library(devilution STATIC Source/minitext.cpp Source/missiles.cpp Source/monster.cpp -# Source/movie.cpp + Source/movie.cpp Source/mpqapi.cpp Source/msgcmd.cpp Source/msg.cpp @@ -159,7 +159,6 @@ add_executable(devilutionx SourceX/miniwin_msg_sdl.cpp SourceX/stub_rand.cpp SourceX/miniwin_thread.cpp - SourceX/movie.cpp SourceX/sound.cpp SourceX/storm.cpp SourceX/storm_net.cpp diff --git a/SourceS/miniwin.h b/SourceS/miniwin.h index 47022040c..a3c58b090 100644 --- a/SourceS/miniwin.h +++ b/SourceS/miniwin.h @@ -252,12 +252,12 @@ typedef struct tagWNDCLASSEXA { typedef unsigned long _fsize_t; /* Could be 64 bits for Win32 */ struct _finddata_t { - unsigned attrib; - time_t time_create; /* -1 for FAT file systems */ - time_t time_access; /* -1 for FAT file systems */ - time_t time_write; - _fsize_t size; - char name[260]; + unsigned attrib; + time_t time_create; /* -1 for FAT file systems */ + time_t time_access; /* -1 for FAT file systems */ + time_t time_write; + _fsize_t size; + char name[260]; }; typedef WORD ATOM; @@ -407,6 +407,7 @@ HWND CreateWindowExA( #define CreateWindowEx CreateWindowExA HWND WINAPI FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName); #define FindWindow FindWindowA +BOOL InvalidateRect(HWND hWnd, const RECT *lpRect, BOOL bErase); BOOL UpdateWindow(HWND hWnd); BOOL ShowWindow(HWND hWnd, int nCmdShow); WINUSERAPI ATOM WINAPI RegisterClassExA(const WNDCLASSEX *lpwcx); diff --git a/SourceX/miniwin.cpp b/SourceX/miniwin.cpp index 8ea01da14..69989d488 100644 --- a/SourceX/miniwin.cpp +++ b/SourceX/miniwin.cpp @@ -278,6 +278,12 @@ HWND CreateWindowExA( return window; } +BOOL InvalidateRect(HWND hWnd, const RECT *lpRect, BOOL bErase) +{ + DUMMY(); + return TRUE; +} + /** * @brief Appears to be used to clear the FB on init */ diff --git a/SourceX/movie.cpp b/SourceX/movie.cpp deleted file mode 100644 index 2e1e0aad6..000000000 --- a/SourceX/movie.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "../3rdParty/libsmacker/smacker.h" -#include "pch.h" - -PALETTEENTRY previousPalette[256]; -BYTE movie_playing; -BOOL loop_movie; // TODO - -void __fastcall play_movie(char *pszMovie, BOOL user_can_close) -{ - DUMMY_PRINT("%s", pszMovie); - - void *video_stream; - - movie_playing = TRUE; - sound_disable_music(TRUE); - sfx_stop(); - effects_play_sound("Sfx\\Misc\\blank.wav"); - - HANDLE directsound; - SFileOpenFile(pszMovie, &directsound); - - BYTE *fileBuffer; - - int bytestoread = SFileGetFileSize(directsound, 0); - fileBuffer = DiabloAllocPtr(bytestoread); - SFileReadFile(directsound, fileBuffer, bytestoread, NULL, 0); - - /* file meta-info */ - unsigned long width, height, nFrames; - unsigned char a_channels[7], a_depth[7]; - unsigned long a_rate[7]; - unsigned char *palette_data; - - smk smacker; - - smacker = smk_open_memory(fileBuffer, bytestoread); - if (smacker != NULL) { - double usPerFrame; - smk_info_all(smacker, NULL, &nFrames, &usPerFrame); - smk_info_video(smacker, &width, &height, NULL); - - smk_info_audio(smacker, NULL, a_channels, a_depth, a_rate); - SDL_AudioDeviceID deviceId; - if (a_depth[0] != 0) { - SDL_AudioSpec audioFormat; - SDL_zero(audioFormat); - audioFormat.freq = a_rate[0]; - audioFormat.format = a_depth[0] == 16 ? AUDIO_S16 : AUDIO_U8; - audioFormat.channels = a_channels[0]; - - deviceId = SDL_OpenAudioDevice(NULL, 0, &audioFormat, NULL, 0); - if (deviceId == 0) { - printf("SDL_OpenAudioDevice: %s\n", SDL_GetError()); - movie_playing = false; - } else { - SDL_PauseAudioDevice(deviceId, 0); /* start audio playing. */ - } - } - - smk_enable_all(smacker, -1); - smk_first(smacker); // Decode first frame - - smk_info_video(smacker, &width, &height, NULL); - SDL_DestroyTexture(texture); - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height); - SDL_RenderSetLogicalSize(renderer, width, height); - - memcpy(previousPalette, orig_palette, 1024); - - - // Copy frame to buffer - SDL_Surface *videoSurface = SDL_CreateRGBSurfaceWithFormatFrom( - smk_get_video(smacker), - width, - height, - 8, - width, - SDL_PIXELFORMAT_INDEX8); - - SDL_Rect src_rect = { 64, 160, 0, 0 }; - SDL_Color colors[256]; - SDL_Palette *vpalette = SDL_AllocPalette(256); - if (SDL_SetSurfacePalette(videoSurface, vpalette) != 0) { - SDL_Log("SDL_SetSurfacePalette: %s\n", SDL_GetError()); - movie_playing = false; - } - - int now; - SDL_Event event; - double frameEnd = SDL_GetTicks() * 1000 + usPerFrame; - - do { - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - case SDL_MOUSEBUTTONDOWN: - if (user_can_close) { - movie_playing = false; - } - break; - case SDL_QUIT: - exit(0); - } - } - - if (a_depth[0] != 0 && SDL_QueueAudio(deviceId, smk_get_audio(smacker, 0), smk_get_audio_size(smacker, 0)) == -1) { - printf("SDL_QueueAudio: %s\n", SDL_GetError()); - } - - now = SDL_GetTicks() * 1000; - if (now >= frameEnd) { - continue; // Skip video if the system is to slow - } - - if (smk_palette_updated(smacker)) { - palette_data = smk_get_palette(smacker); - for (int i = 0; i < 256; i++) { - colors[i].r = palette_data[i * 3 + 0]; - colors[i].g = palette_data[i * 3 + 1]; - colors[i].b = palette_data[i * 3 + 2]; - colors[i].a = SDL_ALPHA_OPAQUE; - - orig_palette[i].peFlags = 0; - orig_palette[i].peRed = palette_data[i * 3 + 0]; - orig_palette[i].peGreen = palette_data[i * 3 + 1]; - orig_palette[i].peBlue = palette_data[i * 3 + 2]; - } - memcpy(logical_palette, orig_palette, 1024); - - if (SDL_SetPaletteColors(vpalette, colors, 0, 256) != 0) { - SDL_Log("SDL_SetPaletteColors: %s\n", SDL_GetError()); - break; - } - } - - if (SDL_BlitSurface(videoSurface, NULL, pal_surface, &src_rect) != 0) { - SDL_Log("SDL_BlitSurface: %s\n", SDL_GetError()); - break; - } - - SetFadeLevel(256); // present frame - - now = SDL_GetTicks() * 1000; - if (now < frameEnd) { - usleep(frameEnd - now); // wait with next frame if the system is to fast - } - - frameEnd += usPerFrame; - if (smk_next(smacker) == SMK_DONE) { - if (loop_movie) - smk_first(smacker); - else - movie_playing = false; - } - } while (movie_playing); - - if (a_depth[0] != 0) { - SDL_ClearQueuedAudio(deviceId); - SDL_CloseAudioDevice(deviceId); - } - smk_close(smacker); - - memcpy(orig_palette, previousPalette, 1024); - - SDL_DestroyTexture(texture); - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); - SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); - } -} diff --git a/SourceX/storm.cpp b/SourceX/storm.cpp index f8c670c17..f6695cd4d 100644 --- a/SourceX/storm.cpp +++ b/SourceX/storm.cpp @@ -1,4 +1,5 @@ #include "../3rdParty/Radon/Radon/include/Radon.hpp" +#include "../3rdParty/libsmacker/smacker.h" #include "pch.h" DWORD nLastError = 0; @@ -360,17 +361,193 @@ BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE fla //{ // UNIMPLEMENTED(); //} -// -// BOOL STORMAPI SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE -// *video) -//{ -// UNIMPLEMENTED(); -//} -// -// BOOL STORMAPI SVidPlayEnd(HANDLE video) -//{ -// UNIMPLEMENTED(); -//} + +double SVidFrameEnd; +double SVidFrameLength; +BYTE SVidLoop; +smk SVidSMK; +PALETTEENTRY SVidPreviousPalette[256]; +SDL_Palette *SVidPalette; +SDL_Surface *SVidSurface; +BYTE *SVidBuffer; +SDL_AudioDeviceID deviceId; + +BOOL STORMAPI SVidPlayBegin(char *filename, int a2, int a3, int a4, int a5, int flags, HANDLE *video) +{ + if (flags & 0x10000 || flags & 0x20000000) { + return FALSE; + } + + SVidLoop = flags & 0x40000; + bool enableVideo = !(flags & 0x100000); + bool enableAudio = !(flags & 0x1000000); + //0x8 // Non-interlaced + //0x200, 0x800 // Upscale video + //0x80000 // Center horizontally + //0x800000 // Edge detection + //0x200800 // Clear FB + + SFileOpenFile(filename, video); + + int bytestoread = SFileGetFileSize(*video, 0); + SVidBuffer = DiabloAllocPtr(bytestoread); + SFileReadFile(*video, SVidBuffer, bytestoread, NULL, 0); + + SVidSMK = smk_open_memory(SVidBuffer, bytestoread); + if (SVidSMK == NULL) { + return FALSE; + } + + deviceId = 0; + unsigned char channels[7], depth[7]; + unsigned long rate[7]; + smk_info_audio(SVidSMK, NULL, channels, depth, rate); + if (enableAudio && depth[0] != 0) { + smk_enable_audio(SVidSMK, 0, enableAudio); + SDL_AudioSpec audioFormat; + SDL_zero(audioFormat); + audioFormat.freq = rate[0]; + audioFormat.format = depth[0] == 16 ? AUDIO_S16 : AUDIO_U8; + audioFormat.channels = channels[0]; + + deviceId = SDL_OpenAudioDevice(NULL, 0, &audioFormat, NULL, 0); + if (deviceId == 0) { + SDL_Log("SDL_OpenAudioDevice: %s\n", SDL_GetError()); + return FALSE; + } else { + SDL_PauseAudioDevice(deviceId, 0); /* start audio playing. */ + } + } + + unsigned long width, height, nFrames; + smk_info_all(SVidSMK, NULL, &nFrames, &SVidFrameLength); + smk_info_video(SVidSMK, &width, &height, NULL); + + smk_enable_video(SVidSMK, enableVideo); + smk_first(SVidSMK); // Decode first frame + + smk_info_video(SVidSMK, &width, &height, NULL); + SDL_DestroyTexture(texture); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height); + SDL_RenderSetLogicalSize(renderer, width, height); + memcpy(SVidPreviousPalette, orig_palette, 1024); + + // Copy frame to buffer + SVidSurface = SDL_CreateRGBSurfaceWithFormatFrom( + smk_get_video(SVidSMK), + width, + height, + 8, + width, + SDL_PIXELFORMAT_INDEX8); + + SVidPalette = SDL_AllocPalette(256); + if (SDL_SetSurfacePalette(SVidSurface, SVidPalette) != 0) { + SDL_Log("SDL_SetSurfacePalette: %s\n", SDL_GetError()); + return FALSE; + } + + SVidFrameEnd = SDL_GetTicks() * 1000 + SVidFrameLength; + + return TRUE; +} + +BOOL SVidLoadNextFrame() +{ + SVidFrameEnd += SVidFrameLength; + + if (smk_next(SVidSMK) == SMK_DONE) { + if (!SVidLoop) { + return FALSE; + } + + smk_first(SVidSMK); + } + + return TRUE; +} + +BOOL __cdecl SVidPlayContinue(void) +{ + if (smk_palette_updated(SVidSMK)) { + SDL_Color colors[256]; + unsigned char *palette_data = smk_get_palette(SVidSMK); + + for (int i = 0; i < 256; i++) { + colors[i].r = palette_data[i * 3 + 0]; + colors[i].g = palette_data[i * 3 + 1]; + colors[i].b = palette_data[i * 3 + 2]; + colors[i].a = SDL_ALPHA_OPAQUE; + + orig_palette[i].peFlags = 0; + orig_palette[i].peRed = palette_data[i * 3 + 0]; + orig_palette[i].peGreen = palette_data[i * 3 + 1]; + orig_palette[i].peBlue = palette_data[i * 3 + 2]; + } + memcpy(logical_palette, orig_palette, 1024); + + if (SDL_SetPaletteColors(SVidPalette, colors, 0, 256) != 0) { + SDL_Log("SDL_SetPaletteColors: %s\n", SDL_GetError()); + return FALSE; + } + } + + if (SDL_GetTicks() * 1000 >= SVidFrameEnd) { + return SVidLoadNextFrame(); // Skip video and audio if the system is to slow + } + + printf("oiasjdf %d\n", deviceId); + if (deviceId && SDL_QueueAudio(deviceId, smk_get_audio(SVidSMK, 0), smk_get_audio_size(SVidSMK, 0)) == -1) { + SDL_Log("SDL_QueueAudio: %s\n", SDL_GetError()); + return FALSE; + } + + if (SDL_GetTicks() * 1000 >= SVidFrameEnd) { + return SVidLoadNextFrame(); // Skip video if the system is to slow + } + + SDL_Rect pal_surface_offset = { 64, 160, 0, 0 }; + if (SDL_BlitSurface(SVidSurface, NULL, pal_surface, &pal_surface_offset) != 0) { + SDL_Log("SDL_BlitSurface: %s\n", SDL_GetError()); + return FALSE; + } + + SetFadeLevel(256); // present frame + + double now = SDL_GetTicks() * 1000; + if (now < SVidFrameEnd) { + usleep(SVidFrameEnd - now); // wait with next frame if the system is to fast + } + + return SVidLoadNextFrame(); +} + +BOOL STORMAPI SVidPlayEnd(HANDLE video) +{ + if (deviceId) { + SDL_ClearQueuedAudio(deviceId); + SDL_CloseAudioDevice(deviceId); + deviceId = 0; + } + + if (SVidSMK) + smk_close(SVidSMK); + + if (SVidBuffer) { + mem_free_dbg(SVidBuffer); + SVidBuffer = NULL; + } + + SFileCloseFile(video); + video = NULL; + + memcpy(orig_palette, SVidPreviousPalette, 1024); + SDL_DestroyTexture(texture); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); + SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); + + return TRUE; +} BOOL STORMAPI SErrDisplayError(DWORD dwErrMsg, const char *logfilename, int logline, const char *message, BOOL allowOption, int exitCode) @@ -457,11 +634,6 @@ void __cdecl SDrawRealizePalette(void) DUMMY(); } -// bool __cdecl SVidPlayContinue(void) -//{ -// UNIMPLEMENTED(); -//} - BOOL __stdcall SFileEnableDirectAccess(BOOL enable) { DUMMY();