Doing XNA in Delphi Prism - xna

I have installed Delphi Prism and XNA Game Studio 3.0. I have managed to translate to Delphi Prism XNA Tutorial 1 "Displaying a 3D Model on the Screen" (http://msdn.microsoft.com/en-us/library/bb197293.aspx).
Project compiles fine, but I cannot load a model. It looks like there is a new "contentproj" type in XNA that is not in Delphi Prism...
Any idea how to get it to work?

You could just manually build the content project using msbuild. It might not have the same integration where you can just add content and change settings in solution explorer ... but it'll do the trick :-)
here is more info about this: http://blogs.msdn.com/shawnhar/archive/2006/11/07/build-it-ahead-of-time.aspx

I have finally managed to get it to work via 1) building "*.contentproj" with MSBuild from command line, 2) coping the resulting "Content" directory as a subdirectory where my Delphi Prism executable is outputted.
It would be nice to have Delphi Prism recognizing *.contentproj automatically and build it automatically.

I haven't done any XNA stuff yet, but here is my best guess :-)
So, the Content Project type is a sub-project for a standard XNA project that just compiles the game content (textures, sound etc) as a nested compile process, correct?
So I would assume that there must be some reference to the sub-project in either the project file or the solution file, perhaps the best way would be to create a simple XMA proj in C# or VB and look at the generated meta-files (csproj, contentproj etc)
Edit:
Oh, I'm suggesting here that you manually create the contentproj file and insert the reference, once you know what they look like, I assume that VS will then allow you to add, delete your content etc
That then just leaves the question of how is the XNA content pipeline compile process is fired, if it doesn't "just happen" that might be a question for marc hoffman et al
Hope this helps a little, its just a guess.
Good to see you in StackOverFlow by the way.
Rgds Tim Jarvis.

According to my knowledge, Prism is only announced and not released. Hence the trial is not a final product. As a RO customer I expect an email come release, but not before except for the announcement of it. Frankly, I don't know that XNA support is finalized or even working yet. You might be premature in trying this, given that the official release of Prism is still almost a month away at the soonest.
I don't know what to tell you to do to fix your problems with XNA, but it would be wise to wait for Prism itself. Until Prism is released I would consider XNA support "pending".

System.reflection can be used to gain access to inner workings of XNA to create xnb files
method Game1.LoadContent;
var
importer : TextureImporter;
texContent : Texture2DContent;
cc : ContentCompiler;
fullPath : String;
fs : FileStream;
args : array[1..7] of System.Object;
begin
spriteBatch := new SpriteBatch(GraphicsDevice);
importer := new TextureImporter;
texContent := importer.Import(’asset.png’, nil) as Texture2DContent;
var compilerType := typeOf(ContentCompiler);
cc := compilerType.GetConstructors(BindingFlags.NonPublic or BindingFlags.Instance)[0].Invoke(nil) as ContentCompiler;
var compileMethod := compilerType.GetMethod("Compile", BindingFlags.NonPublic or BindingFlags.Instance);
fullPath := ‘assestName.xnb’;
fs := File.Create(fullPath);
args[1] := fs;
args[2] := texContent;
args[3] := TargetPlatform.Windows;
args[4] := GraphicsProfile.Reach;
args[5] := true;
args[6] := fullPath;
args[7] := fullPath;
compileMethod.Invoke
(
cc,
args
);
//SpriteTexture := Content.Load(’assetName’);
end;

Related

How to open an external App as MDIChild or Modal Dialog in my App as if it is another form of my App

My company has a huge with-delphi-written 3-Million-line-code mostly-database-related Application, and we are responsible to support this program. This Application has a MainForm as fsMDIForm and other forms are fsMDIChild which are created programmatically when they are needed.
In our team, we have worked with other different programming languages like C++, C#, Python, VB, etc. An idea is to make some part of the program with another programming language like C# in Visual Studio and open it in our App.
For example in another C# project in our company we have a form which lets user select a convartable-to-PDF file (such as pictures, documents, ...) with special GUI and convert it to PDF/A for archiving. It allows user to attach multiple PDFs as well. Now the project manager has told us to use this code in our Delphi project. There are many ways to do so, such as making a DLL and call it from Delphi or simply convert it to EXE and call it from Delphi and wait for it to be closed and so on.
Sometimes writing it again in Delphi is the only solution, but it would be great, if I would put such a code in a simple C# project and make an EXE from it, then I run this EXE file as Modal/MDIChild-Form in the Delphi application, as if it is a part of the main App.
What an absolutely bad thing I did:
procedure TEditEmailDlg.btnAttachFileClick(Sender: TObject);
var
tf: string;
begin
tf := TempFolder + 'FCDAA5F7-E26D-4C54-9514-68BDEC845AE3.Finished';
ShellExecute(Handle, 'open', 'C:\Program Files (x86)\GL-K-S\tools\2PDFA.exe', '', '', SW_SHOWNORMAL);
repeat
Sleep(300);
until FileExists(tf);
with TStringList.Create do
begin
LoadFromFile(tf); // Selected and converted filenames
...
end;
...
DeleteFile(tf);
end;
As you see it waits for the App to be closed, but it is not like a MDI form of the project and the project is going to be not respounding.
If it is a good idea, please let me know how can I do it, and if not, why and what is the better solution to prevent rewriting forms and codes behind them in Delphi.
As you have the code of both Delphi (D) and C# or C++ (C) you can do a little modifications on both applications to use either Windows Messages or Shared Memory.
I used Windows Messages 10 years ago, sorry I don't have the code right now.
Windows Messages :
D will send a window handle (WH) to C as a command parameter when running it.
When C finish or any other reason, it will notify D by sending a custom message to WH.
Shared Memory :
D will send the name of shared memory to C as a command parameter when running it.
In both cases C will send back a window handle (WH2) to D, then D will use SetParent() function to make MyForm inside D is the parent for this window WH2.
SetParent(WH2, MyForm.Handle);
MoveWindow(WH2, 0, 0, MyForm.ClientWidth, MyForm.ClientHeight, True);
D will close MyForm when it get a notify message from C telling it that C is about to close.
You may also use GetWindowRect() function to get width and height of WH2 to adjust MyForm size.
var r: TRect;
GetWindowRect(WH2, r);
MyForm.ClientWidth := r.Right - r.Left;
MyForm.ClientHeight := r.Bottom - r.Top;

How to replace glut32.dll library with freeglut.dll in Delphi XE easily (program stops suddenly)

I have the following issue.
I'm using Glut openGL for drawing certain elements in my application written in Delphi. The library file I'm using is called glut32.dll (placed where the EXE file is standing)
Now I decided to compile my app in 64-bit as other libraries it is using are going to be updated only for 64-bit. All fine, but the one thing that stops me is the glut32.dll (it is 32-bit). As the Glut project is not supported for many years already I found the freeglut alternative which claim to be replacement for the original Glut: https://freeglut.sourceforge.net/, and downloaded the freeglut.dll from here: www.transmissionzero.co.uk/software/freeglut-devel/ for MSVC.
As I looked at the .h header files it seems more or less the same as my code translation is in the *.pas files.
So I tried to just load the freeglut.dll instead of glut32.dll (dll is set to the correct dll name in the function below)
procedure LoadGlut(const dll: String);
begin
FreeGlut;
hDLL := LoadLibrary(PChar(dll));
if hDLL = 0 then raise Exception.Create('Could not load Glut from ' + dll);
#glutInit := GetProcAddress(hDLL, 'glutInit');
#glutInitDisplayMode := GetProcAddress(hDLL, 'glutInitDisplayMode');
#glutCreateWindow := GetProcAddress(hDLL, 'glutCreateWindow');
#glutCreateSubWindow := GetProcAddress(hDLL, 'glutCreateSubWindow');
#glutDestroyWindow := GetProcAddress(hDLL, 'glutDestroyWindow');
#glutPostRedisplay := GetProcAddress(hDLL, 'glutPostRedisplay');
...
It is loading with no errors and so on, also the procedures in it, but when the application start and reach a point to use one of these functions it just stop the debugger with no error message (like pressing Ctrl+F2).
procedure DrawArrow(P1, P2: TRPoint; Color: TRGBAColor);
var
R : Real;
begin
DrawLine(P1, P2, Color);
glColor4fv(#Color[0]);
glPushMatrix;
SetZAxis(P2, P1);
R := VectorModulus(VectorDifference(P1,P2));
glTranslated(0, 0, R);
SetSymbolScale;
glTranslated(0, 0, -ARROW_L);
glutSolidCone(ARROW_W/2, ARROW_L, SOLID_SLICES, SOLID_STACKS);
glPopMatrix;
glPopMatrix;
end;
The debugger shut itself at glutSolidCone(ARROW_W/2, ARROW_L, SOLID_SLICES, SOLID_STACKS); This function is defined in freeglut as well.
EDIT: If I call other simple function like glutInitDisplayMode it doesn't stop, so it seems that the library is correctly loaded. But it still keeps shutting down at glutSolidCone or other drawing functions.
I don't have much experience of using these header files and dll that comes with it, but my Delphi code should be a good translation in this case? Or not? I don't know how to debug this.
What is the way to adapt my code in order to fit freeglut in it. It should be something small I think as most of the things should be the same.
Thank you for the help
It seems that just replacing glut32.dll with freeglut.dll won't do the job properly as I guess functions inside differs a bit (or simply renaming freeglut.dll --> glut32.dll also fails). However I found a workaround published by NVIDIA: NVIDIA Cg Toolkit
It is not supported since 2013, but when installed it brings the dll version of glut32 both for 32-bit and 64-bit development. Quickly try it and it seems to work and cover what I have as definition in Glut.pas.
So if you need 64-bit version and replacement of glut32.dll it can be downloaded from there.
Meanwhile if somebody convert the freeglut headers (.h) to Delphi code it would be great as at the end the Freeglut projecy is still maintained, up-to-date and add some more useful functions in addition to the original Glut. This conversion is still beyond my knowledge.

Delphi 10.4 localization issues

I'm trying Delphi 10.4. Localizing Windows applications was working like a charm in the past, but now when I dynamically load the RC DLL file, it only changes RCDATA, and not the "String Table" any more.
I was using this code (as quick resume)
NewInst := LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE);
....
CurModule.ResInstance := NewInstance;
FileName is the DLL file that has the resources (RCDATA and "String Table") that I could edit with "Resource Hacker" software, and can see that it contains "String table" Inside as expected.
It works fine for RCDATA (all forms are getting translated) but not "String table" anymore that is contained into Resourcestring section of any .pas file, and all string remains in the original language.
It was working fine in previous Delphi version (like 10.2) and I do not know why it fails with this version.
There is another solution. Disable the new caching by assigning LoadResStringFunc to nil. A good place to do that is in the beginning of the program.
begin
>>> ADD THIS to disable the caching
LoadResStringFunc := nil;
>>>
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Core problem
The problem is that resourcestrings are cached now, and you do not have access to clear the cache after you loaded new resource data :(
See https://quality.embarcadero.com/browse/RSP-30853
(and drop a vote if you think it has to be fixed)
Work-around
I "Cloned" the resourcestring caching mechanism into a separate unit and re-routed LoadResStringFunc to my cloned unit. Here I allow access to the resstringcache, and thus can clear it after loading the new resource.

reading SVN:externals from working copy

Until recently it was simple to read all the SVN:Externals referenced in a subversion working copy by just reading some text files stored in the .svn subdirectory. With the change to a new on disk structure using mysql tables this is no longer that simple.
I want to update an internally used tool that used to read that list of externals to using the new structure. The Tool is written in Delphi 2007 so I would prefer some code written in Delphi.
There is Version Insight for RAD Studio on sourceforge which might contain some code to do the trick but I wonder if any body else has maybe already gone through the work of extracting the required parts from that project or has an alternative.
You can also do it programmatically, using the Subversion client DLLs. Here is a minimal example written in Delphi XE:
program svnext;
{$APPTYPE CONSOLE}
uses
SysUtils,
SvnClient;
procedure Main;
var
SvnClient: TSvnClient;
SvnItem: TSvnItem;
begin
// Subversion client DLL directory; here I simply use the .exe's directory
// (I copied the DLLs there manually.)
BaseDllDir := ExtractFilePath(ParamStr(0));
SvnClient := nil;
SvnItem := nil;
try
SvnClient := TSvnClient.Create;
SvnClient.Initialize;
SvnItem := TSvnItem.Create(SvnClient, nil, ParamStr(1));
Writeln(SvnItem.PropValues['svn:externals']);
finally
SvnItem.Free;
SvnClient.Free;
end;
end;
begin
try
Main;
except
on E: Exception do
begin
ExitCode := 1;
Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
end;
end;
end.
You might have to tweak the code for Delphi 2007. It seems Version Insight has evolved in the meantime and lost (some of) the backward compatibility.
If you can call the svn executable, it is pretty easy to find all the externals stored in your repository :
svn propget -R svn:externals .
will return :
first/path/to/external - name_of_first_external http://first_repos/that/is/in/external
second/path/to/external - name_of_second_external http://second_repos/that/is/in/external
Like others said, call the SVN executable. You can integrate this with the Delphi Tools menu using this technique:
http://delphi.wikia.com/wiki/Adding_TortoiseSVN_to_the_Tools_menu
To add to that article, it's also VERY handy to have an "open folder here" entry that opens Windows Explorer for the folder of the file being edited. Here's the "tool properties" for that:
Title: Open Folder Here
Program: explorer.exe
Parameters: $PATH($EDNAME)
If you have this, then you've got all of TortoiseSVN at your fingertips.

Using Delphi to modify the version information of another delphi program

I was wanting to create a small tool in Delphi which can update the Delphi version information in another exe file. I know several existing utilities are out there for this but I need full programmatic control and would prefer no shelling out to the command line, etc.
After a web search I couldn't find any Delphi source code examples of modifying version information in an exe, could anyone provide some code or direction?
I can't give a complete answer, but I can get you started. There is an article at DelphiDabbler.com that fills in how to get to the version information out of a file. GetFileVersionInfo is the Windows API to do that. To set it, I believe UpdateResource is the Windows API function you'll need to use. There is another article at CodeProject that covers this, using C, but it should give you a solid idea of what needs to be done.
Good luck!
Edit: I found some code on the Delphi newsgroups that might give you some more help:
// Credit to Michael Winter for this code!
Sz := GetLen;
GetMem(Data, Sz);
try
GetData(Data, Sz);
HFile := BeginUpdateResource(PChar(FileName), false);
if HFile = 0 then
RaiseLastWin32Error;
DoDiscard := true;
try
if not UpdateResource(HFile, RT_VERSION, PChar(1), 0, Data, Sz) then
RaiseLastWin32Error;
DoDiscard := false;
finally
if not EndUpdateResource(HFile, DoDiscard) then
RaiseLastWin32Error;
end;
finally
FreeMem(Data);
end;
It's just a snippet, and will require some work on your part, but that's the lion's share of the work!
There's also Colin Wilson's XN Resource Editor with source code which might help.

Resources