Advertisement

Win32 - Questions about Settimer/ TimeSetEvent

Started by February 23, 2020 08:26 AM
18 comments, last by Airbatz 4 years, 8 months ago

I have always felt it was due to lack of interest (for this particular problem), since most people are not fussed with their resources being in one local directory. Everything can be done with enough time and dedication, I agree. At least one other project I am working on is using PlaySound() so thank you for sharing how you went about it. I have read through that article on MIDI, but it is a distance from where my abilities lie at the moment. I'm simply curious as to whether someone has used such a feature in an existing program. There is also the slight issue with latency before the MIDI begins to play, which wasn't present in Windows 98.

None

Well, there are almost always workarounds, so yeah, not much is “impossible”, but I think it's natural people would choose the API/library that is intended to do it “out the box” if figuring out the work around is more complex than using the low level or library option.

As a point of interest, I believe since Windows Vista the various audio API's are actually just libraries that then use the Core Audio API (WASAPI is part of this). Mostly this is just of interest to see how some of the API's might actually be implemented, but you absolutely could also use it directly with your own software mixing if desired (I believe this is also where a lot of the “no hardware acceleration” came from, DirectSound and XAudio2 do software mixing then send Core Audio the result).

Windows 10 had some enhancements for MIDI to help music production people. Not sure if any of that is useful/relevant. Of course all the old MIDI API's will still work, but maybe Microsoft re-implementing stuff as wrappers caused some latency?

Advertisement

@SyncViews

Personally, I want to use the Windows API only, so no part of the program requires external libraries. It makes the process more difficult sure, but I'm very particular about how something is done ?

Interesting article, I wasn't aware that DirectSound/Music interacted with Core Audio. I just wish MS had updated the existing basic multimedia functions with improvements as well. I do agree on the wrappers potentially causing latency because I've read of people getting mixed results using the MCI on Windows 10. I also found this page, which discusses the reason for the latency, which is apparently a call to Sleep(). I wonder if there is a way around this without modifying any files.

None

Airbatz said:
I just wish MS had updated the existing basic multimedia functions with improvements as well.

I think they just did the absolute minimum to stop the masses complaining in Vista (and plenty of other things people were complaining about). Most programs needing high quality (video games, video players, music players, etc.) would be using one of the other API's (where people still complained, e.g. due to hardware acceleration). So as long things like alert/notification sounds, button click sounds, play sample sound buttons/tools, etc., in GUI apps still “work”, I guess never a priority.

And they have a collection of API's (with lots of confusing overlaps and styles while they try and push .NET and such) for "new code", so I don't think ever considered any enhancements to some of those APIs.

I think “Windows API” is a bit of a blurred term here, the current DirectX has been a part of the Windows SDK for almost 10 years (June 2010 was last DirectX SDK, and since then a lot of “non-core” parts of DirectX have been deprecated/removed), and such things have certainly always been a Microsoft API (and doing very low level stuff interacting with hardware/drivers you can't really just do yourself), there not some 3rd party thing you get off github.

@SyncViews

Oddly enough, I never experienced any issues when using Vista. It makes sense that the aformentioned applications would be the focus, but a little attention to detail couldn't have hurt. But it's Microsoft after all.

I understand the DirectX is a part of the SDK, but there is still a requirement on the user to have it on their system to run a program using those features, so older machines will have compatibility issues, hence why I'd prefer a solution via the MCI.

I've made some more changes to my program. I've made the back buffer global, according to the suggestion in theForgers tutorial. Am I missing something, or is that the way to do it? I've noticed no difference when running the program.

#include <windows.h>
#include "resource.h"
#include <stdlib.h>
#include <time.h>

#define WINDOW_CLASS_NAME "DEMOCLASS"
#define WINDOW_WIDTH 405
#define WINDOW_HEIGHT 295

HDC hdc;
HDC hdcMem;
HDC hdcBuffer;
HBITMAP hbmBuffer;
HBITMAP hbmOldBuffer;

HBITMAP g_hbmSprite = NULL;
HBITMAP g_hbmTitle = NULL;
HBITMAP g_hbmBackground = NULL;

HICON hMainIcon;
DWORD dw_timestart;
DWORD dw_timestop;
float f_cycle_t;

struct SpriteAnimation
{
  int frames;
  int direction;
  float animation_counter;
  float angle_counter;
  float sprite_speed;
  float drift_speed;
  float animation_speed;
  float x;
  float y;

}SpriteAnimation;

struct SpriteAnimation Sprite_Slow = { 0, 0, 0, 0, 0.07, 0.04, 0.05, 0, -7 };
struct SpriteAnimation Sprite_Fast = { 0, 0, 0, 0, 0.10, 0.02, 0.03, 0, -48 };
struct SpriteAnimation Sprite_Inst[2];

void DrawMain( HDC hdc, RECT* prc )
{
  hdcBuffer    = CreateCompatibleDC( hdc );
  hbmBuffer    = CreateCompatibleBitmap( hdc, prc->right, prc->bottom );
  hbmOldBuffer = (HBITMAP)SelectObject( hdcBuffer, hbmBuffer );
  hdcMem       = CreateCompatibleDC( hdc );

  FillRect(hdcBuffer, prc, (HBRUSH)GetStockObject(WHITE_BRUSH));

  // title
  HBITMAP hbmOld = (HBITMAP)SelectObject( hdcMem, g_hbmTitle );
  TransparentBlt( hdcBuffer, 50, 24, 297, 39, hdcMem, 0, 0, 297, 39, RGB( 255, 0, 255 ) );

   // background
  HBITMAP hbmOld2 = (HBITMAP)SelectObject( hdcMem, g_hbmBackground );
  TransparentBlt( hdcBuffer, 112, 90, 186, 91, hdcMem, 0, 0, 186, 91, RGB( 255, 0, 255 ) );

  // sprite
  HBITMAP hbmOld3 = (HBITMAP)SelectObject( hdcMem, g_hbmSprite );
  TransparentBlt( hdcBuffer, SpriteAnimation.x, SpriteAnimation.y, 15, 15, hdcMem, 15*(SpriteAnimation.frames%28), 0, 15, 15, RGB( 255, 0, 255 ) );

  // blit double buffer to window
  BitBlt( hdc, 0, 0, prc->right, prc->bottom, hdcBuffer, 0, 0, SRCCOPY );

  SelectObject( hdcMem, hbmOld );
  DeleteDC( hdcMem );

  SelectObject( hdcMem, hbmOld2 );
  DeleteDC( hdcMem );

  SelectObject( hdcMem, hbmOld3 );
  DeleteDC( hdcMem );

  SelectObject( hdcBuffer, hbmOldBuffer );
  DeleteDC( hdcBuffer );
  DeleteObject( hbmBuffer );
}

None

Airbatz said:
I've made some more changes to my program. I've made the back buffer global, according to the suggestion in theForgers tutorial. Am I missing something, or is that the way to do it? I've noticed no difference when running the program.

I am pretty sure you should be able to re-use a bitmap across multiple paints. But that doesn't look to me like what you did, while the variable itself is global, DrawMain is creating and destroying it every time, like a local variable.

Personally I would store all that stuff in some sort of “not-quite global” graphics object, but the end result is pretty much the same unless you have multiple-windows or such.

What difference were you expecting? Fractionally better performance? The main benefit that comes to mind is you could only paint some of it when there are changes as an optimisation, but that could get fairly complex and I don't think is needed for modern hardware.

Airbatz said:
Oddly enough, I never experienced any issues when using Vista. It makes sense that the aformentioned applications would be the focus, but a little attention to detail couldn't have hurt. But it's Microsoft after all.

Did you have a creative sound card? That is the main thing I recall people complaining about, because people lost all their hardware acceleration and EAX when Vista made DirectSound(3D) a software stack, and XAudio2 a little after was software as well. So all those cards were reduced to maybe a slightly better digital-analogue converter over basic models, onboard, or USB headsets. For OpenAL I think Creative provided a complete hardware driver for (by-passing Microsoft's audio system entirely), but I don't recall that being particularly well supported by games either pre-Vista or new.

Airbatz said:
I understand the DirectX is a part of the SDK, but there is still a requirement on the user to have it on their system to run a program using those features, so older machines will have compatibility issues, hence why I'd prefer a solution via the MCI.

It definitely comes with Windows 10 for all the currently supported components, I am 99% sure on Windows 8/8.1. Not so sure on Windows 7 (with updates) as the DX SDK was only merged into Windows later.

Similar deal for OpenGL, but I think technically Windows OS ships with 1.1 and everything else is part of the AMD/Intel/Nvidia drivers through the extension system.

Advertisement

The Windows GDI doesn't like it when you create and destroy items multiple times, often it will break completely. Create the back buffer once and then re-use it but as has been pointed out, you are creating and destroying on every cycle.

@SyncViews

By “creating and destroying it” are you referring to the variables in DrawMain? I tried the following:

HDC hdc;
RECT rect;
HDC hdcMem       = CreateCompatibleDC( hdc );
HDC hdcBuffer    = CreateCompatibleDC( hdc );
HBITMAP hbmBuffer    = CreateCompatibleBitmap( hdc, rect.right, rect.bottom );
HBITMAP hbmOldBuffer = (HBITMAP)SelectObject( hdcBuffer, hbmBuffer );

.. and get a blank window.

Here's what WM_PAINT looks like. I have the InvalidateRect in the message loop.

 case WM_PAINT:
      {
        PAINTSTRUCT ps;
        hdc = BeginPaint( hwnd, &ps );

        GetClientRect( hwnd, &rect );
        dw_timestart = timeGetTime();

        DrawMain( hdc, rect );
        AnimateFrames ();
        UpdateSpritePosition();

        dw_timestop = timeGetTime();
        EndPaint( hwnd, &ps );

        f_cycle_t = dw_timestop - dw_timestart;
      }
      return 0;

I was expecting that maybe the CPU usage would drop a notch or two. Mainly I just wanted the advantage for future projects that could use it, though none of them deal with window resizing or heaps of windows. I do want to blit the sprite in a seperate function, but that's about it.

I'm fairly certain that I had a Creative soundcard, but at that time I didn't notice anything wrong with it. Then again, I didn't really play many games on that OS, or do much programming on it either.

The target OS for my programs will be Windows 7, XP and 2000, so that's another reason for wanting to stay away from DirectX. I have considered OpenGL but find it to be overly complex for something that isn't even a game. It's only the MIDI from resource that prompted me to try it.

None

@rafaelsantana

It occured to me that that might be a problem if there are more graphical effects happening at once. I'm slowly improving the program little by little.

EDIT: sorry for double-post.

None

This topic is closed to new replies.

Advertisement