Merge pull request 'HashLeenkx Updates!' (#44) from Onek8/LNXSDK:main into main
Reviewed-on: #44
@ -1,16 +1,55 @@
 | 
				
			|||||||
package kha.graphics4;
 | 
					package kha.graphics4;
 | 
				
			||||||
 | 
					using StringTools;
 | 
				
			||||||
import kha.Blob;
 | 
					import kha.Blob;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FragmentShader {
 | 
					class FragmentShader {
 | 
				
			||||||
	public var _shader: Pointer;
 | 
						public var _shader: Pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(sources: Array<Blob>, files: Array<String>) {
 | 
						public function new(sources: Array<Blob>, files: Array<String>) {
 | 
				
			||||||
		initShader(sources[0]);
 | 
							//initShader(sources[0]);
 | 
				
			||||||
 | 
							var shaderBlob: Blob = null;
 | 
				
			||||||
 | 
							var shaderFile: String = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#if kha_opengl
 | 
				
			||||||
 | 
							final expectedExtension = ".glsl";
 | 
				
			||||||
 | 
							#elseif kha_direct3d11
 | 
				
			||||||
 | 
							final expectedExtension = ".d3d11";
 | 
				
			||||||
 | 
							#elseif kha_direct3d12
 | 
				
			||||||
 | 
							final expectedExtension = ".d3d12";
 | 
				
			||||||
 | 
							#elseif kha_metal
 | 
				
			||||||
 | 
							final expectedExtension = ".metal";
 | 
				
			||||||
 | 
							#elseif kha_vulkan
 | 
				
			||||||
 | 
							final expectedExtension = ".spirv";
 | 
				
			||||||
 | 
							#else
 | 
				
			||||||
 | 
							final expectedExtension = ".glsl";
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (sources != null && files != null) {
 | 
				
			||||||
 | 
								for (i in 0...files.length) {
 | 
				
			||||||
 | 
									if (files[i].endsWith(expectedExtension)) {
 | 
				
			||||||
 | 
										shaderBlob = sources[i];
 | 
				
			||||||
 | 
										shaderFile = files[i];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shaderBlob == null && sources != null && sources.length > 0) {
 | 
				
			||||||
 | 
								trace('Warning: Could not find shader with extension ${expectedExtension}. Falling back to sources[0]: ${files != null && files.length > 0 ? files[0] : "Unknown"}');
 | 
				
			||||||
 | 
								shaderBlob = sources[0];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shaderBlob != null) {
 | 
				
			||||||
 | 
								initShader(shaderBlob);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								trace('Error: No suitable fragment shader source found!');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function initShader(source: Blob): Void {
 | 
						function initShader(source: Blob): Void {
 | 
				
			||||||
		_shader = kinc_create_fragmentshader(source.bytes.getData(), source.bytes.getData().length);
 | 
							//_shader = kinc_create_fragmentshader(source.bytes.getData(), source.bytes.getData().length);
 | 
				
			||||||
 | 
							_shader = kinc_create_fragmentshader(source.bytes.getData(), source.length); // Use source.length here
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static function fromSource(source: String): FragmentShader {
 | 
						public static function fromSource(source: String): FragmentShader {
 | 
				
			||||||
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
@ -694,8 +694,8 @@ def build_success():
 | 
				
			|||||||
                if wrd.lnx_audio == 'Disabled':
 | 
					                if wrd.lnx_audio == 'Disabled':
 | 
				
			||||||
                    cmd.append('--nosound')
 | 
					                    cmd.append('--nosound')
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
        elif state.target.startswith(('windows-hl', 'linux-hl', 'macos-hl', 'Hashlink')):
 | 
					        elif state.target.startswith(('windows-hl', 'linux-hl', 'macos-hl')):
 | 
				
			||||||
            log.info(f"Attempting to run Hashlink/C target: {state.target}")
 | 
					            log.info(f"Runtime Hashlink/C target: {state.target}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            hl_build_dir, _, _ = lnx.utils.hashlink_paths(state.target)
 | 
					            hl_build_dir, _, _ = lnx.utils.hashlink_paths(state.target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -763,7 +763,6 @@ def build_success():
 | 
				
			|||||||
                if not compile_success:
 | 
					                if not compile_success:
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Path is typically: <build_dir>/<Platform>/<Configuration>/<ProjectName>.exe
 | 
					 | 
				
			||||||
                exe_path = os.path.join(hl_build_dir, platform, build_mode, proj_name + '.exe')
 | 
					                exe_path = os.path.join(hl_build_dir, platform, build_mode, proj_name + '.exe')
 | 
				
			||||||
                if not os.path.isfile(exe_path):
 | 
					                if not os.path.isfile(exe_path):
 | 
				
			||||||
                    exe_path = os.path.join(hl_build_dir, build_mode, proj_name + '.exe')
 | 
					                    exe_path = os.path.join(hl_build_dir, build_mode, proj_name + '.exe')
 | 
				
			||||||
@ -772,27 +771,70 @@ def build_success():
 | 
				
			|||||||
                        return
 | 
					                        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                log.info(f"Found compiled executable: {exe_path}")
 | 
					                log.info(f"Found compiled executable: {exe_path}")
 | 
				
			||||||
                cmd = [exe_path]
 | 
					                
 | 
				
			||||||
                exe_dir = os.path.dirname(exe_path)
 | 
					                dest_exe_name = proj_name + '.exe'
 | 
				
			||||||
                log.info(f"Changing CWD to: {exe_dir}")
 | 
					                base_build_dir = lnx.utils.get_fp_build()
 | 
				
			||||||
                os.chdir(exe_dir)
 | 
					                dest_dir = os.path.join(base_build_dir, state.target)
 | 
				
			||||||
 | 
					                dest_path = os.path.join(dest_dir, dest_exe_name)
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    shutil.move(exe_path, dest_path)
 | 
				
			||||||
 | 
					                    cmd = [dest_path]
 | 
				
			||||||
 | 
					                except Exception as e:
 | 
				
			||||||
 | 
					                    cmd = [exe_path]
 | 
				
			||||||
 | 
					                os.chdir(dest_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            elif state.target in ('linux-hl', 'macos-hl'):
 | 
					            elif state.target in ('linux-hl', 'macos-hl'):
 | 
				
			||||||
                 log.error(f"Compilation for {state.target} is not yet implemented in build_success.")
 | 
					                wrd = bpy.data.worlds['Lnx']
 | 
				
			||||||
                 return
 | 
					                paths = lnx.utils.hashlink_paths(state.target)
 | 
				
			||||||
            else:
 | 
					                hl_build_dir = paths[0]
 | 
				
			||||||
                 log.error(f"Running logic for target {state.target} is not defined (expected Krom or Hashlink/C).")
 | 
					                # TO DO switch from default Release
 | 
				
			||||||
                 return
 | 
					                build_mode = 'Release'
 | 
				
			||||||
 | 
					                proj_name = lnx.utils.blend_name()
 | 
				
			||||||
 | 
					                exe_path = str(hl_build_dir + "/" + build_mode) 
 | 
				
			||||||
 | 
					                if not exe_path:
 | 
				
			||||||
 | 
					                    log.error(f"Build finished, but could not find the executable for {state.target}.")
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                makefile_path = os.path.join(exe_path, 'makefile')
 | 
				
			||||||
 | 
					                if not os.path.isfile(makefile_path):
 | 
				
			||||||
 | 
					                    log.error(f"Makefile not found at '{makefile_path}'. Cannot compile C code.")
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if cmd:
 | 
					                make_cmd = ['make']
 | 
				
			||||||
                log.info(f"Executing final command: {' '.join(cmd)}")
 | 
					
 | 
				
			||||||
 | 
					                log.info(f"Compiling C code using 'make' in directory '{exe_path}'...")
 | 
				
			||||||
 | 
					                log.info(f"Make command: {' '.join(make_cmd)}")
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    state.proc_play = run_proc(cmd, play_done)
 | 
					                    result = subprocess.run(make_cmd, cwd=exe_path, check=True, capture_output=True, text=True, encoding='utf-8')
 | 
				
			||||||
                except Exception:
 | 
					                    log.info("'make' compilation successful.")
 | 
				
			||||||
                    traceback.print_exc()
 | 
					                except subprocess.CalledProcessError as e:
 | 
				
			||||||
            else:
 | 
					                    log.error(f"'make' compilation failed with return code {e.returncode}.")
 | 
				
			||||||
                log.error("No command generated to run.")
 | 
					                    log.error(f"Make Error Output:\n{e.stderr}")
 | 
				
			||||||
 | 
					                    return 
 | 
				
			||||||
 | 
					                except FileNotFoundError:
 | 
				
			||||||
 | 
					                    log.error("'make' command not found. Ensure 'make' is installed and in your system's PATH.")
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					                except Exception as e:
 | 
				
			||||||
 | 
					                    log.error(f"An unexpected error occurred running make: {e}")
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                log.info(f"Found compiled executable: {exe_path}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                dest_exe_name = lnx.utils.safesrc(wrd.lnx_project_name + '-' + wrd.lnx_project_version)
 | 
				
			||||||
 | 
					                base_build_dir = lnx.utils.get_fp_build()
 | 
				
			||||||
 | 
					                dest_dir = os.path.join(base_build_dir, state.target) 
 | 
				
			||||||
 | 
					                og_path = os.path.join(exe_path, dest_exe_name)
 | 
				
			||||||
 | 
					                dest_path = os.path.join(dest_dir, dest_exe_name)
 | 
				
			||||||
 | 
					                os.makedirs(dest_dir, exist_ok=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    log.info(f"Moving '{og_path}' to '{dest_dir}'...")
 | 
				
			||||||
 | 
					                    shutil.move(og_path, dest_dir) 
 | 
				
			||||||
 | 
					                    cmd = [dest_path] 
 | 
				
			||||||
 | 
					                except Exception as e:
 | 
				
			||||||
 | 
					                    log.error(f"Failed to move executable: {e}. Attempting to run from original location.")
 | 
				
			||||||
 | 
					                    cmd = [exe_path]
 | 
				
			||||||
 | 
					                os.chdir(dest_dir)
 | 
				
			||||||
 | 
					                log.info(f"Hashlink final command: {' '.join(cmd)}")
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            state.proc_play = run_proc(cmd, play_done)
 | 
					            state.proc_play = run_proc(cmd, play_done)
 | 
				
			||||||
        except Exception:
 | 
					        except Exception:
 | 
				
			||||||
 | 
				
			|||||||