diff --git a/gamemaker/TheorafileGMS/TheorafileGMS.yyp b/gamemaker/TheorafileGMS/TheorafileGMS.yyp new file mode 100644 index 0000000..1579ae7 --- /dev/null +++ b/gamemaker/TheorafileGMS/TheorafileGMS.yyp @@ -0,0 +1,55 @@ +{ + "resources": [ + {"id":{"name":"TheorafileGMS","path":"extensions/TheorafileGMS/TheorafileGMS.yy",},"order":0,}, + {"id":{"name":"TheorafileGMS_Scripts","path":"scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.yy",},"order":0,}, + {"id":{"name":"YUVToRGB","path":"shaders/YUVToRGB/YUVToRGB.yy",},"order":0,}, + {"id":{"name":"Room1","path":"rooms/Room1/Room1.yy",},"order":0,}, + ], + "Options": [ + {"name":"Linux","path":"options/linux/options_linux.yy",}, + {"name":"macOS","path":"options/mac/options_mac.yy",}, + {"name":"Main","path":"options/main/options_main.yy",}, + {"name":"Windows","path":"options/windows/options_windows.yy",}, + {"name":"operagx","path":"options/operagx/options_operagx.yy",}, + ], + "isDnDProject": false, + "isEcma": false, + "tutorialPath": "", + "configs": { + "name": "Default", + "children": [], + }, + "RoomOrderNodes": [ + {"roomId":{"name":"Room1","path":"rooms/Room1/Room1.yy",},}, + ], + "Folders": [ + {"folderPath":"folders/Sprites.yy","order":1,"resourceVersion":"1.0","name":"Sprites","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Tile Sets.yy","order":2,"resourceVersion":"1.0","name":"Tile Sets","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Sounds.yy","order":3,"resourceVersion":"1.0","name":"Sounds","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Paths.yy","order":4,"resourceVersion":"1.0","name":"Paths","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Scripts.yy","order":5,"resourceVersion":"1.0","name":"Scripts","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Shaders.yy","order":6,"resourceVersion":"1.0","name":"Shaders","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Fonts.yy","order":7,"resourceVersion":"1.0","name":"Fonts","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Timelines.yy","order":8,"resourceVersion":"1.0","name":"Timelines","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Objects.yy","order":9,"resourceVersion":"1.0","name":"Objects","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Rooms.yy","order":10,"resourceVersion":"1.0","name":"Rooms","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Sequences.yy","order":11,"resourceVersion":"1.0","name":"Sequences","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Animation Curves.yy","order":12,"resourceVersion":"1.0","name":"Animation Curves","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Notes.yy","order":13,"resourceVersion":"1.0","name":"Notes","tags":[],"resourceType":"GMFolder",}, + {"folderPath":"folders/Extensions.yy","order":14,"resourceVersion":"1.0","name":"Extensions","tags":[],"resourceType":"GMFolder",}, + ], + "AudioGroups": [ + {"targets":-1,"resourceVersion":"1.3","name":"audiogroup_default","resourceType":"GMAudioGroup",}, + ], + "TextureGroups": [ + {"isScaled":true,"autocrop":true,"border":2,"mipsToGenerate":0,"groupParent":null,"targets":-1,"resourceVersion":"1.3","name":"Default","resourceType":"GMTextureGroup",}, + ], + "IncludedFiles": [], + "MetaData": { + "IDEVersion": "2.3.6.595", + }, + "resourceVersion": "1.4", + "name": "TheorafileGMS", + "tags": [], + "resourceType": "GMProject", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/extensions/TheorafileGMS/TheorafileGMS.dll b/gamemaker/TheorafileGMS/extensions/TheorafileGMS/TheorafileGMS.dll new file mode 100644 index 0000000..304725a Binary files /dev/null and b/gamemaker/TheorafileGMS/extensions/TheorafileGMS/TheorafileGMS.dll differ diff --git a/gamemaker/TheorafileGMS/extensions/TheorafileGMS/TheorafileGMS.yy b/gamemaker/TheorafileGMS/extensions/TheorafileGMS/TheorafileGMS.yy new file mode 100644 index 0000000..6f899da --- /dev/null +++ b/gamemaker/TheorafileGMS/extensions/TheorafileGMS/TheorafileGMS.yy @@ -0,0 +1,114 @@ +{ + "optionsFile": "options.json", + "options": [], + "exportToGame": true, + "supportedTargets": -1, + "extensionVersion": "0.0.1", + "packageId": "", + "productId": "", + "author": "", + "date": "2021-11-19T16:53:50.9842329-08:00", + "license": "", + "description": "", + "helpfile": "", + "iosProps": false, + "tvosProps": false, + "androidProps": false, + "installdir": "", + "files": [ + {"filename":"TheorafileGMS.dll","origname":"","init":"","final":"","kind":1,"uncompress":false,"functions":[ + {"externalName":"TheorafileGMS_Open","kind":1,"help":"TheorafileGMS_Open(filename)","hidden":false,"returnType":1,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_Open","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_Close","kind":1,"help":"TheorafileGMS_Close(filePointer)","hidden":false,"returnType":1,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_Close","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_Reset","kind":1,"help":"TheorafileGMS_Reset(filePointer)","hidden":false,"returnType":1,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_Reset","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_HasVideo","kind":1,"help":"TheorafileGMS_HasVideo(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_HasVideo","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_Width","kind":1,"help":"TheorafileGMS_Width(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_Width","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_Height","kind":1,"help":"TheorafileGMS_Height(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_Height","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_FPS","kind":1,"help":"TheorafileGMS_FPS(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_FPS","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_RequiredBufferSizeInBytes","kind":1,"help":"TheorafileGMS_RequiredBufferSizeInBytes(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_RequiredBufferSizeInBytes","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_EndOfStream","kind":1,"help":"TheorafileGMS_EndOfStream(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_EndOfStream","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_ReadVideo","kind":1,"help":"TheorafileGMS_ReadVideo(filePointer, bufferAddress, numFrames)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + 1, + 2, + ],"resourceVersion":"1.0","name":"TheorafileGMS_ReadVideo","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_UVWidth","kind":1,"help":"TheorafileGMS_UVWidth(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_UVWidth","tags":[],"resourceType":"GMExtensionFunction",}, + {"externalName":"TheorafileGMS_UVHeight","kind":1,"help":"TheorafileGMS_UVHeight(filePointer)","hidden":false,"returnType":2,"argCount":0,"args":[ + 1, + ],"resourceVersion":"1.0","name":"TheorafileGMS_UVHeight","tags":[],"resourceType":"GMExtensionFunction",}, + ],"constants":[],"ProxyFiles":[],"copyToTargets":64,"order":[ + {"name":"TheorafileGMS_Open","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_Close","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_Reset","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_HasVideo","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_Width","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_Height","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_UVWidth","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_UVHeight","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_FPS","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_RequiredBufferSizeInBytes","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_EndOfStream","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + {"name":"TheorafileGMS_ReadVideo","path":"extensions/TheorafileGMS/TheorafileGMS.yy",}, + ],"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMExtensionFile",}, + ], + "classname": "", + "tvosclassname": null, + "tvosdelegatename": null, + "iosdelegatename": "", + "androidclassname": "", + "sourcedir": "", + "androidsourcedir": "", + "macsourcedir": "", + "maccompilerflags": "", + "tvosmaccompilerflags": "", + "maclinkerflags": "", + "tvosmaclinkerflags": "", + "iosplistinject": "", + "tvosplistinject": "", + "androidinject": "", + "androidmanifestinject": "", + "androidactivityinject": "", + "gradleinject": "", + "androidcodeinjection": "", + "hasConvertedCodeInjection": false, + "ioscodeinjection": "", + "tvoscodeinjection": "", + "iosSystemFrameworkEntries": [], + "tvosSystemFrameworkEntries": [], + "iosThirdPartyFrameworkEntries": [], + "tvosThirdPartyFrameworkEntries": [], + "IncludedResources": [], + "androidPermissions": [], + "copyToTargets": 64, + "iosCocoaPods": "", + "tvosCocoaPods": "", + "iosCocoaPodDependencies": "", + "tvosCocoaPodDependencies": "", + "parent": { + "name": "Extensions", + "path": "folders/Extensions.yy", + }, + "resourceVersion": "1.2", + "name": "TheorafileGMS", + "tags": [], + "resourceType": "GMExtension", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/options/linux/options_linux.yy b/gamemaker/TheorafileGMS/options/linux/options_linux.yy new file mode 100644 index 0000000..4978896 --- /dev/null +++ b/gamemaker/TheorafileGMS/options/linux/options_linux.yy @@ -0,0 +1,25 @@ +{ + "option_linux_display_name": "Created with GameMaker Studio 2", + "option_linux_version": "1.0.0.0", + "option_linux_maintainer_email": "", + "option_linux_homepage": "http://www.yoyogames.com", + "option_linux_short_desc": "", + "option_linux_long_desc": "", + "option_linux_splash_screen": "${base_options_dir}/linux/splash/splash.png", + "option_linux_display_splash": false, + "option_linux_icon": "${base_options_dir}/linux/icons/64.png", + "option_linux_start_fullscreen": false, + "option_linux_allow_fullscreen": false, + "option_linux_interpolate_pixels": true, + "option_linux_display_cursor": true, + "option_linux_sync": false, + "option_linux_resize_window": false, + "option_linux_scale": 0, + "option_linux_texture_page": "2048x2048", + "option_linux_enable_steam": false, + "option_linux_disable_sandbox": false, + "resourceVersion": "1.0", + "name": "Linux", + "tags": [], + "resourceType": "GMLinuxOptions", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/options/mac/options_mac.yy b/gamemaker/TheorafileGMS/options/mac/options_mac.yy new file mode 100644 index 0000000..73e249f --- /dev/null +++ b/gamemaker/TheorafileGMS/options/mac/options_mac.yy @@ -0,0 +1,33 @@ +{ + "option_mac_display_name": "Created with GameMaker Studio 2", + "option_mac_app_id": "com.company.game", + "option_mac_version": "1.0.0.0", + "option_mac_output_dir": "~/gamemakerstudio2", + "option_mac_team_id": "", + "option_mac_signing_identity": "Developer ID Application:", + "option_mac_copyright": "", + "option_mac_splash_png": "${base_options_dir}/mac/splash/splash.png", + "option_mac_icon_png": "${base_options_dir}/mac/icons/1024.png", + "option_mac_installer_background_png": "${base_options_dir}/mac/splash/installer_background.png", + "option_mac_menu_dock": false, + "option_mac_display_cursor": true, + "option_mac_start_fullscreen": false, + "option_mac_allow_fullscreen": false, + "option_mac_interpolate_pixels": true, + "option_mac_vsync": false, + "option_mac_resize_window": false, + "option_mac_enable_retina": false, + "option_mac_scale": 0, + "option_mac_texture_page": "2048x2048", + "option_mac_build_app_store": false, + "option_mac_allow_incoming_network": false, + "option_mac_allow_outgoing_network": false, + "option_mac_app_category": "Games", + "option_mac_enable_steam": false, + "option_mac_disable_sandbox": false, + "option_mac_apple_sign_in": false, + "resourceVersion": "1.0", + "name": "macOS", + "tags": [], + "resourceType": "GMMacOptions", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/options/main/options_main.yy b/gamemaker/TheorafileGMS/options/main/options_main.yy new file mode 100644 index 0000000..2153b8f --- /dev/null +++ b/gamemaker/TheorafileGMS/options/main/options_main.yy @@ -0,0 +1,20 @@ +{ + "option_gameguid": "033bbd73-fc75-4dcc-b6c5-a6325ac19f66", + "option_gameid": "0", + "option_game_speed": 60, + "option_mips_for_3d_textures": false, + "option_draw_colour": 4294967295, + "option_window_colour": 255, + "option_steam_app_id": "0", + "option_sci_usesci": false, + "option_author": "", + "option_lastchanged": "", + "option_spine_licence": false, + "option_template_image": "${base_options_dir}/main/template_image.png", + "option_template_icon": "${base_options_dir}/main/template_icon.png", + "option_template_description": null, + "resourceVersion": "1.2", + "name": "Main", + "tags": [], + "resourceType": "GMMainOptions", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/options/operagx/options_operagx.yy b/gamemaker/TheorafileGMS/options/operagx/options_operagx.yy new file mode 100644 index 0000000..8d52513 --- /dev/null +++ b/gamemaker/TheorafileGMS/options/operagx/options_operagx.yy @@ -0,0 +1,11 @@ +{ + "option_operagx_version": "1.0.0.0", + "option_operagx_game_name": "${project_name}", + "option_operagx_interpolate_pixels": true, + "option_operagx_scale": 0, + "option_operagx_texture_page": "2048x2048", + "resourceVersion": "1.0", + "name": "operagx", + "tags": [], + "resourceType": "GMOperaGXOptions", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/options/windows/options_windows.yy b/gamemaker/TheorafileGMS/options/windows/options_windows.yy new file mode 100644 index 0000000..44cc31c --- /dev/null +++ b/gamemaker/TheorafileGMS/options/windows/options_windows.yy @@ -0,0 +1,36 @@ +{ + "option_windows_display_name": "Created with GameMaker Studio 2", + "option_windows_executable_name": "${project_name}.exe", + "option_windows_version": "1.0.0.0", + "option_windows_company_info": "YoYo Games Ltd", + "option_windows_product_info": "Created with GameMaker Studio 2", + "option_windows_copyright_info": "", + "option_windows_description_info": "A GameMaker Studio 2 Game", + "option_windows_display_cursor": true, + "option_windows_icon": "${base_options_dir}/windows/icons/icon.ico", + "option_windows_save_location": 0, + "option_windows_splash_screen": "${base_options_dir}/windows/splash/splash.png", + "option_windows_use_splash": false, + "option_windows_start_fullscreen": false, + "option_windows_allow_fullscreen_switching": false, + "option_windows_interpolate_pixels": false, + "option_windows_vsync": false, + "option_windows_resize_window": false, + "option_windows_borderless": false, + "option_windows_scale": 0, + "option_windows_copy_exe_to_dest": false, + "option_windows_sleep_margin": 10, + "option_windows_texture_page": "2048x2048", + "option_windows_installer_finished": "${base_options_dir}/windows/installer/finished.bmp", + "option_windows_installer_header": "${base_options_dir}/windows/installer/header.bmp", + "option_windows_license": "${base_options_dir}/windows/installer/license.txt", + "option_windows_nsis_file": "${base_options_dir}/windows/installer/nsis_script.nsi", + "option_windows_enable_steam": false, + "option_windows_disable_sandbox": false, + "option_windows_steam_use_alternative_launcher": false, + "option_windows_use_x64": false, + "resourceVersion": "1.1", + "name": "Windows", + "tags": [], + "resourceType": "GMWindowsOptions", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/rooms/Room1/Room1.yy b/gamemaker/TheorafileGMS/rooms/Room1/Room1.yy new file mode 100644 index 0000000..f69dcfa --- /dev/null +++ b/gamemaker/TheorafileGMS/rooms/Room1/Room1.yy @@ -0,0 +1,52 @@ +{ + "isDnd": false, + "volume": 1.0, + "parentRoom": null, + "views": [ + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + {"inherit":false,"visible":false,"xview":0,"yview":0,"wview":1366,"hview":768,"xport":0,"yport":0,"wport":1366,"hport":768,"hborder":32,"vborder":32,"hspeed":-1,"vspeed":-1,"objectId":null,}, + ], + "layers": [ + {"instances":[],"visible":true,"depth":0,"userdefinedDepth":false,"inheritLayerDepth":false,"inheritLayerSettings":false,"gridX":32,"gridY":32,"layers":[],"hierarchyFrozen":false,"resourceVersion":"1.0","name":"Instances","tags":[],"resourceType":"GMRInstanceLayer",}, + {"spriteId":null,"colour":4278190080,"x":0,"y":0,"htiled":false,"vtiled":false,"hspeed":0.0,"vspeed":0.0,"stretch":false,"animationFPS":15.0,"animationSpeedType":0,"userdefinedAnimFPS":false,"visible":true,"depth":100,"userdefinedDepth":false,"inheritLayerDepth":false,"inheritLayerSettings":false,"gridX":32,"gridY":32,"layers":[],"hierarchyFrozen":false,"resourceVersion":"1.0","name":"Background","tags":[],"resourceType":"GMRBackgroundLayer",}, + ], + "inheritLayers": false, + "creationCodeFile": "", + "inheritCode": false, + "instanceCreationOrder": [], + "inheritCreationOrder": false, + "sequenceId": null, + "roomSettings": { + "inheritRoomSettings": false, + "Width": 1366, + "Height": 768, + "persistent": false, + }, + "viewSettings": { + "inheritViewSettings": false, + "enableViews": false, + "clearViewBackground": false, + "clearDisplayBuffer": true, + }, + "physicsSettings": { + "inheritPhysicsSettings": false, + "PhysicsWorld": false, + "PhysicsWorldGravityX": 0.0, + "PhysicsWorldGravityY": 10.0, + "PhysicsWorldPixToMetres": 0.1, + }, + "parent": { + "name": "Rooms", + "path": "folders/Rooms.yy", + }, + "resourceVersion": "1.0", + "name": "Room1", + "tags": [], + "resourceType": "GMRoom", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.gml b/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.gml new file mode 100644 index 0000000..2977657 --- /dev/null +++ b/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.gml @@ -0,0 +1,34 @@ +function Theorafile_Open(filename) +{ + var address = TheorafileGMS_Open(filename); + if (address == 0) + { + show_debug_message("Could not open theora video at filename: " + filename); + return; + } + + var _yWidth = TheorafileGMS_Width(filename); + var _yHeight = TheorafileGMS_Height(filename); + var _frames_per_second = TheorafileGMS_FPS(filename); + var _uvWidth = TheorafileGMS_UVWidth(filename); + var _uvHeight = TheorafileGMS_UVHeight(filename); + + return { + handle: ptr(address), + yWidth: _yWidth, + yHeight: _yHeight, + uvWidth: _uvWidth, + uvHeight: _uvHeight + framesPerSecond: _frames_per_second, + }; +} + +function Theorafile_Close(pointer) +{ + TheorafileGMS_Close(pointer) +} + +function Theorafile_Play(pointer) +{ + +} diff --git a/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.yy b/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.yy new file mode 100644 index 0000000..f1cc5c8 --- /dev/null +++ b/gamemaker/TheorafileGMS/scripts/TheorafileGMS_Scripts/TheorafileGMS_Scripts.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "Scripts", + "path": "folders/Scripts.yy", + }, + "resourceVersion": "1.0", + "name": "TheorafileGMS_Scripts", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.fsh b/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.fsh new file mode 100644 index 0000000..68412ff --- /dev/null +++ b/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.fsh @@ -0,0 +1,30 @@ +uniform sampler2D y_tex; +uniform sampler2D u_tex; +uniform sampler2D v_tex; + +varying vec2 v_vTexcoord; + +void main() +{ + const vec3 offset = vec3(-0.0625, -0.5, -0.5); + + /* ITU-R BT.709 */ + const vec3 Rcoeff = vec3(1.164, 0.000, 1.793); + const vec3 Gcoeff = vec3(1.164, -0.213, -0.533); + const vec3 Bcoeff = vec3(1.164, 2.112, 0.000); + + vec3 yuv; + + yuv.x = texture2D(y_tex, v_vTexcoord).r; + yuv.y = texture2D(u_tex, v_vTexcoord).r; + yuv.z = texture2D(v_tex, v_vTexcoord).r; + yuv += offset; + + vec4 color; + color.x = dot(yuv, Rcoeff); + color.y = dot(yuv, GCoeff); + color.z = dot(yuv, BCoeff); + color.w = 1.0; + + gl_FragColor = color; +} diff --git a/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.vsh b/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.vsh new file mode 100644 index 0000000..033b69e --- /dev/null +++ b/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.vsh @@ -0,0 +1,10 @@ +attribute vec3 in_Position; // (x,y,z) +attribute vec2 in_TextureCoord; // (u,v) + +varying vec2 v_vTexcoord; + +void main() +{ + v_vTexcoord = in_TextureCoord; + gl_Position = vec4(in_Position, 1.0); +} diff --git a/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.yy b/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.yy new file mode 100644 index 0000000..5293ced --- /dev/null +++ b/gamemaker/TheorafileGMS/shaders/YUVToRGB/YUVToRGB.yy @@ -0,0 +1,11 @@ +{ + "type": 1, + "parent": { + "name": "Shaders", + "path": "folders/Shaders.yy", + }, + "resourceVersion": "1.0", + "name": "YUVToRGB", + "tags": [], + "resourceType": "GMShader", +} \ No newline at end of file diff --git a/src/TheorafileGMS.c b/src/TheorafileGMS.c index 2115e3e..583e2a0 100644 --- a/src/TheorafileGMS.c +++ b/src/TheorafileGMS.c @@ -28,7 +28,7 @@ #include "theorafile.h" #include "SDL.h" -static inline void LogError(char* string) +static inline void LogError(const char* string) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", string); } @@ -89,6 +89,80 @@ double TheorafileGMS_Height(char* filePointer) return (double)height; } +int TheorafileGMS_INTERNAL_UVWidthAndHeight(OggTheora_File* file, int *uvWidth, int *uvHeight) +{ + int yWidth; + int yHeight; + th_pixel_fmt format; + tf_videoinfo(file, &yWidth, &yHeight, NULL, &format); + + int width; + int height; + + if (format == TH_PF_420) + { + width = yWidth / 2; + height = yHeight / 2; + } + else if (format == TH_PF_422) + { + width = yWidth / 2; + height = yHeight; + } + else if (format == TH_PF_444) + { + width = yWidth; + height = yHeight; + } + else + { + LogError("Unrecognized YUV format!"); + return 1; + } + + if (uvWidth != NULL) + { + *uvWidth = width; + } + + if (uvHeight != NULL) + { + *uvHeight = height; + } + + return 0; +} + +double TheorafileGMS_UVWidth(char* filePointer) +{ + OggTheora_File* file = (OggTheora_File*)filePointer; + + int uvWidth; + int err = TheorafileGMS_INTERNAL_UVWidthAndHeight(file, &uvWidth, NULL); + + if (err) + { + return 0; + } + + return (double)uvWidth; +} + +double TheorafileGMS_UVHeight(char* filePointer) +{ + OggTheora_File* file = (OggTheora_File*)filePointer; + + int uvHeight; + int err = TheorafileGMS_INTERNAL_UVWidthAndHeight(file, NULL, &uvHeight); + + if (err) + { + return 0; + } + + return (double)uvHeight; +} + double TheorafileGMS_FPS(char* filePointer) { OggTheora_File* file = (OggTheora_File*)filePointer; @@ -97,6 +171,37 @@ double TheorafileGMS_FPS(char* filePointer) return fps; } +int TheorafileGMS_INTERNAL_RequiredBufferSizeInBytes(OggTheora_File* file) +{ + int yWidth; + int yHeight; + th_pixel_fmt format; + tf_videoinfo(file, &yWidth, &yHeight, NULL, &format); + + int uvWidth; + int uvHeight; + + int err = TheorafileGMS_INTERNAL_UVWidthAndHeight(file, &uvWidth, &uvHeight); + + if (err) + { + return -1; + } + + int yuvDataLen = ( + (yWidth * yHeight) + + (uvWidth * uvHeight * 2) + ); + + return yuvDataLen; +} + +double TheorafileGMS_RequiredBufferSizeInBytes(char* filePointer) +{ + OggTheora_File* file = (OggTheora_File*)filePointer; + return TheorafileGMS_INTERNAL_RequiredBufferSizeInBytes(file) * 4; /* game maker can only take RGBA32 lol */ +} + double TheorafileGMS_EndOfStream(char* filePointer) { OggTheora_File* file = (OggTheora_File*)filePointer; @@ -112,5 +217,29 @@ void TheorafileGMS_Reset(char* filePointer) double TheorafileGMS_ReadVideo(char* filePointer, char* buffer, double numFrames) { OggTheora_File* file = (OggTheora_File*)filePointer; - return (double)tf_readvideo(file, buffer, (int)numFrames); + int yWidth; + int yHeight; + th_pixel_fmt format; + tf_videoinfo(file, &yWidth, &yHeight, NULL, &format); + + int requiredBufferSize = TheorafileGMS_INTERNAL_RequiredBufferSizeInBytes(file); + if (requiredBufferSize <= 0) + { + LogError("Unrecognized format! Bailing!"); + return -1; + } + + /* Game Maker doesnt have R8 textures so we have to do this padding bullshit */ + char* yuvBuffer = SDL_malloc(requiredBufferSize * 4); + SDL_memset(yuvBuffer, 0, requiredBufferSize * 4); + + int updated = tf_readvideo(file, yuvBuffer, (int)numFrames); + + for (int i = 0; i < requiredBufferSize; i += 1) + { + SDL_memcpy(buffer + (i * 4), yuvBuffer + i, sizeof(char)); + } + + SDL_free(yuvBuffer); + return (double)updated; } diff --git a/src/TheorafileGMS.h b/src/TheorafileGMS.h index 7de2251..cf3084b 100644 --- a/src/TheorafileGMS.h +++ b/src/TheorafileGMS.h @@ -48,7 +48,10 @@ extern "C" THEORAFILEGMSAPI double TheorafileGMS_HasVideo(char* filePointer); THEORAFILEGMSAPI double TheorafileGMS_Width(char* filePointer); THEORAFILEGMSAPI double TheorafileGMS_Height(char* filePointer); + THEORAFILEGMSAPI double TheorafileGMS_UVWidth(char* filePointer); + THEORAFILEGMSAPI double TheorafileGMS_UVHeight(char* filePointer); THEORAFILEGMSAPI double TheorafileGMS_FPS(char* filePointer); + THEORAFILEGMSAPI double TheorafileGMS_RequiredBufferSizeInBytes(char* filePointer); THEORAFILEGMSAPI double TheorafileGMS_EndOfStream(char* filePointer); /* returns whether a texture update is needed or not */