|
|
I have been trying to achive a smooth horizontal scrolling text on the bottom of the screen in one of my applications.
It seems to be almost impossible to get it to run without choppy movements.
My scroller is double buffered, and using microsecond accurate timing to calculate the distance to move pr frame. Still it seems to be moving at a variable rate stuttering on its way from the right to left side of the screen...
I have searched for several days now for examples/techniques how to achive smooth scrolling text, but all the examples I have tried which claims to be smooth scrolling isn't... (Most just implement double buffering, but that only removes flicker).
Some sites suggest sub pixel accure rendering, antialiasing, and that these problems are related to how lcd screens work. I have tried regular GUI programming in C# (graphics/bitmap drawing), DirectDraw (C++ and C#), Direct3D (C++ and C#), and OpenGL (C++).
It's kind of frustrating that something that was possible to do on a Commodore 64 with 1 MHz is so hard to replicate on a 2 GHz modern PC. I guess it goes a long way to show the usefullness of custom chips to help the CPU.
If anyone have some suggestions or even better example code on how to achive such a thing I would appriciate it a lot! (Preferably I would like to run this without a 3D accelerated graphics card.)
|
|
|
|
|
If you can't get it working using one of Microsoft's Direct X libraries you're doing something wrong. It is definitely the way to go...
Create a panel or any kind of container. Create a 3D Device which renders on that object, and create a render loop, which renders and scrolls your text.
|
|
|
|
|
I was struggling with the same issue, but just got it working smoothly with DirectX and C# using the source here:
http://directx4vb.vbgamer.com/DirectX4VB/TUT_DX9Start.asp[^]
You do have to change/upgrade the DrawText() statements a little bit; add null as first param, remove the rect (just use x & y) and textFormat.
Use a scrollPos variable for the X pos.
Can we finally get rid of our C64
|
|
|
|
|
For some videocards (f.e. GeForce 8600GT) it is neccessary to set the PresentParameters.PresentationInterval to PresentInterval.One to get it V-Synced. The Device.Present() method seems to waits for the vertical blanking interval now (and adapts to the vertical refresh rate of your videocard).
PresentInterval: The relationship between the adapter refresh rate and the rate at which Present() operations are completed.
Hope this helps anyone out there!
|
|
|
|
|
Are you really using microsecond accurate timing? The fixed-step timing in Entanglar works pretty well and is very accurate over long periods - but it certainly varys. GDI should have no problems handling this. The debug renderer for Entanglar uses GDI, which is pretty crappy, but I have no worries getting smooth animation out of it.
Make sure you have switched the correct extra styles in your panel constructor as well:
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
Also take a hard look at your timing code and make sure you really understand what is going on. Post the core part of your timing code if you like...
|
|
|
|
|
Here is the code from my attempt in C# with GDI.
private void timer1_Tick_1(object sender, EventArgs e)
{
stopWatch.Stop();
distance = speed * (float)(stopWatch.Elapsed.TotalMilliseconds);
position -= distance; if (position < -300.0f) position = 500.0f;
stopWatch.Reset();
stopWatch.Start();
g.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
g.DrawString("This is a test... This is a test...", new Font("Arial", 30), Brushes.Black, position, 15.0f);
outGfx.DrawImageUnscaled(bmp, 0, 0);
}
Note1: Using System.Diagnostics Stopwatch which features elapsed time in milliseconds and fractions of a millsecond.
Note2: the speed variable is fixed at 0.1f
Note3: The timer is running at 1 ms interval.
Note4: My memory bitmap (bmp) is 500x100
|
|
|
|
|
Regarding Note3, the timer won't be raising events at anything close to a 1ms interval. The scheduling quanta of the kernel is something like 50ms on XP. If the timer you are using raises events on the form's message loop then the accuracy will be even worse. If it uses the thread pool, then you will likely hit some horrible concurrency issues.
Keep it simple for a start. Set your timer to around 100ms. Call Control.Invalidate from the timer event. Hook/override OnPaint for the control. Use DateTime.Now to handle positioning for your animation. That should be more than accurate enough for your needs.
|
|
|
|
|
It won't move very smooth with just 10 updates pr second.
Anyways I moved it all to a thread (with a 5 ms sleep), and call invalidate from the thread, and overide the paint method.
The result is the same, it still doesnt appear to be moving smooth, and the graphics do flicker a bit even when I use
double buffering.
If anyone would like to test my code I have packed the test project (VS2008): http://www.codeinvaders.com/code/ScrollTest.zip
|
|
|
|
|
As I mentioned, you can't sleep a thread for 5ms. If the kernel gives a timeslice to another thread, then it will give a fullquanta, which is around 50ms on XP.
Take the simple example:
<br />
private void Form1_Load(object sender, EventArgs e)<br />
{<br />
startTime = DateTime.Now;<br />
g = Graphics.FromImage(bmp);<br />
g.Clear(Color.White);<br />
this.Invalidate();<br />
}<br />
<br />
protected override void OnPaint(PaintEventArgs e)<br />
{<br />
position = (float) (((DateTime.Now - startTime).TotalSeconds * 100f) % 800f) - 300f;<br />
Draw();<br />
this.Invalidate();<br />
}
This runs smooth as hell. You don't need to play with fancy timers to get smooth animation. The reason Entanglar uses a rather complicated phase-locked-loop setup is to minimise drift over a long time (which is fairly critical for stable multiplayer).
|
|
|
|
|
string strType = "hello"
ApplyCleansingRulesFurther(out strType, strIssued);
private void ApplyCleansingRulesFurther(out string strType, string strIssued)
{
////????
if (strType.ToLower().Trim().Contains("hello there"))
////????
{
if (strIssued.ToLower().Trim().Contains("yes"))
{
strType = strType.Replace("hello there", "Hello There!");
}
}
}
--the above code does not compile.
error is on where I placed ????
It says use of unassigned out parameter strType
Thanks
|
|
|
|
|
out parameters mean that they do not have to be instantiated, so your choice is either to instantiate it in the method, or change the type to a ref parameter.
|
|
|
|
|
Not sure what you mean.
Could you correct my sample code so that I can understand please?
Thanks
|
|
|
|
|
string strType = "hello";
ApplyCleansingRulesFurther(ref strType, strIssued);
private void ApplyCleansingRulesFurther(ref string strType, string strIssued)
{
if (strType.ToLower().Trim().Contains("hello there"))
{
if (strIssued.ToLower().Trim().Contains("yes"))
{
strType = strType.Replace("hello there", "Hello There!");
}
}
}
|
|
|
|
|
I am now using ref and it works.
Is it better to use ref or out?
It seems using ref is easier.
Thanks
|
|
|
|
|
That depends on what you want to accomplish. You should use ref for a parameter that is both input and output, and use out for a parameter that is only output.
Preferably you should avoid the ref or out keywords entirely, unless they really benefit the code. In your method you should just pass in the string as a regular parameter, and return the result as the return value of the method:
string type = "hello";
type = ApplyCleansingRulesFurther(type, issued);
private string ApplyCleansingRulesFurther(string type, string issued) {
if (type.ToLower().Trim().Contains("hello there")) {
if (issued.ToLower().Trim().Contains("yes")) {
type = type.Replace("hello there", "Hello There!");
}
}
return type;
}
(I cleaned up the code a bit... No data type prefixes on variables in a strongly typed language. Note that it's pointless to trim a string when you are using Contains on the result. Also note that eventhough the if statement handles upper case letters, the Replace call doesn't.)
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
|
I'm making an application for a small sized business, it's coming along nicely. So far I've been using text documents and CSV files to store the data that they want. Nothing big, no need for an online database. My question now is this, with no 'formal' training in C# I have a couple of questions, firstly what is the purpose of app.config? Secondly, how would you store user settings of an application? I am currently testing around and tyring to explore the advantages of storing them in plain text file, or even in the registry.
What do you think?
P.S. Take it easy, if it's a dumb question apologies in advance.
|
|
|
|
|
The app.config is a damn handy thing, and unless you have some fairly bizarre requirements, you should make use of it. The only bad thing about the app.config is that assemblies (DLLs) cannot easily have their own app.config.
User settings (settings that can be changed by the user) are stored in a user config file in the appropriate special (hidden) folder (ProgramData in Vista). Google "c# settings" or something like that to get an idea of using them, or even search CodeProject articles. I know there are at least three articles here that deal with user settings.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote: The app.config is a damn handy thing, and unless you have some fairly bizarre requirements, you should make use of it. The only bad thing about the app.config is that assemblies (DLLs) cannot easily have their own app.config.
User settings (settings that can be changed by the user) are stored in a user config file in the appropriate special (hidden) folder (ProgramData in Vista). Google "c# settings" or something like that to get an idea of using them, or even search CodeProject articles. I know there are at least three articles here that deal with user settings.
Thanks, I'm going to take a deeper look. I had no idea what it was for I figured it was an internal file or something produced by the compiler related to the build, not for execution.
|
|
|
|
|
EliottA wrote: how would you store user settings of an application?
I just use an XML file stored in the user's APPDATA directory.
|
|
|
|
|
Hi All
I have a calendar on one form and a schedule on the other form.
I have this code on the calendar
new Schedule().Show();
Every time i click on the calendar it opens a dialog box and if i keep clocking it will keep on open more dialogs.
I want it so that when i click on a date i will show me on the Schedule.
Can anyone help me?
Thanks in advance .
|
|
|
|
|
try using a singleton and then just update the form using methods you call from the first form
|
|
|
|
|
Well, your design is flawed. You should
0) make the Schedule form global
1) allocate it once in the constructor of the main form (making its default Visible state as false)
2) when you do whatever it is you do to cause the schedule form to be displayed, simply call schedule.Show().
3) Make the OK button on the schdeule form hide the form instead of closing it.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
from a curiosity pov is this similar to a singleton pattern or a modification on it?
|
|
|
|