Do you remember that?
The AMIGA Boing Ball, was a mythical object in the computer industry created during a night at the 1984 CES by Dale Luck and R. J. Mical.
This reworked 64-bit version is only
19 Kb in size including the icon resource.
It is using the same concept exposed in the T-Rex animation posted here:
https://www.codeproject.com/Articles/763207/T-Rex-animationexcept that the multi-frame animation has been replaced by a real 3D object.
It uses a popup transparent layered window to render the sphere animation with OpenGL.
Not much to say about the C++ source code, that should be self explanatory for those familiar with the low level procedural SDK programming style.
RenderAnimation is the masterpiece where the Amiga logo and the OpenGL 3D sphere are mixed together into the same DC using
DrawAndSetupAlphaChannel.
void RenderAnimation(IN HWND hWnd) {
RECT rw = { 0 };
BLENDFUNCTION bf = { 0 };
POINT lp = { 0 }, ptSrc = { 0 };
SIZEL lpSize = { 0 };
LONG_PTR graphics = 0, imgAttr = 0, lpCallback = 0, callbackdata = 0;
static long imgW, imgH, xDir, yDir;
GetWindowRect(hWnd, &rw);
lpSize.cx = rw.right - rw.left; lpSize.cy = rw.bottom - rw.top;
lp.x = rw.left; lp.y = rw.top;
HDC DesktopDC = GetDC(0);
// Create our memory DC
HDC hMemDC = CreateCompatibleDC(DesktopDC);
HBITMAP hBmp = CreateDIB(DesktopDC, lpSize.cx, lpSize.cy, 32);
if (hBmp) {
SelectObject(hMemDC, hBmp);
if (gP.shadow == 0) {
WCHAR szFile[MAX_PATH] = { 0 };
Path_Combine(szFile, EXEresource(), L"amiga.png");
GdipLoadImageFromFile(szFile, gP.shadow);
if (gP.shadow) { GetImageSize(gP.shadow, imgW, imgH); }
}
// Draw the OpenGL scene
DrawTheScene();
wglMakeCurrent(gP.gldc, gP.glrc);
SwapBuffers(gP.gldc);
DrawAndSetupAlphaChannel(hMemDC, -13, -14);
if (gP.shadow) {
if (GdipCreateFromHDC(hMemDC, graphics) == 0) {
GdipSetInterpolationMode(graphics, 2);
GdipDrawImageRectRectI(graphics, gP.shadow, 1, 14, imgW, imgH, 0, 0, imgW, imgH, 2, imgAttr, lpCallback, callbackdata);
GdipDeleteGraphics(graphics);
}
}
// Update the layered window
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.AlphaFormat = AC_SRC_ALPHA; // Use source alpha
bf.SourceConstantAlpha = 255;
UpdateLayeredWindow (hWnd, DesktopDC, &lp, &lpSize, hMemDC, &ptSrc, 0, &bf, ULW_ALPHA);
DeleteObject(hBmp);
DeleteDC(hMemDC);
// Move the layered window around the screen
long PlayIt = 0;
if (xDir == 0) { xDir = MOVE_STEP; yDir = MOVE_STEP; }
if (xDir > 0) {
if (gP.x + FRAME_SizeX - 21 > GetSystemMetrics(SM_CXSCREEN)) { xDir = -xDir; PlayIt = -1; }
} else {
if (gP.x < 0) { xDir = -xDir; PlayIt = -1; }
}
if (yDir > 0) {
if (gP.y + FRAME_SizeY - 21 > GetSystemMetrics(SM_CYSCREEN)) { yDir = -yDir; PlayIt = -1; }
} else {
if (gP.y < 0) { yDir = -yDir; PlayIt = -1; }
}
if (PlayIt) { PlayWav(); }
gP.x += xDir; gP.y += yDir;
MoveWindow(hWnd, gP.x, gP.y, FRAME_SizeX, FRAME_SizeY + LOGO_SizeY, 0);
}
ReleaseDC(0, DesktopDC);
}
To stop the demo, catch the ball and press the ESCAPE key. Or shut it down from the task bar.
Nostalgia of my eighties!
...