Here it is another enhanced version of the tunnel. Compiled in 10Kb with tiny c, almost no wasting cpu.
Code: Select all
#define cdXPos CW_USEDEFAULT
#define cdYPos CW_USEDEFAULT
#define cdXSize 320 //cdYSize*1.6
#define cdYSize 200
#define cdColFondo 0
#define MAIN_ICON 100 // IDI_APPLICATION
#define cdVCursor IDC_ARROW
#define cdVBarTipo 0
#define cdVBtnTipo WS_OVERLAPPEDWINDOW
#define cdIdTimer 1
#define DIB_RGB_COLORS 0
#define deg2rad 0.01745329251994 // pi/180
#define cdPI 3.1415926535897932384626433832795
#define cd2PI 6.283185307179586476925286766559
#define maxpoints 32
// Prototipos de funciones
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
// Variables globales
int *pMainDIB = NULL;
int vdxClient, vdyClient;
BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER),cdXSize,-cdYSize,1,32,0,0,0,0,0,0};
int Tangle[cdXSize*2][cdYSize*2], Tdepth[cdXSize*2][cdYSize*2];
int Texture[256][256], Distbuffer[256][256];
double xcoords[maxpoints], ycoords[maxpoints];
double tmp = 0;
double dist (double x, double y, double xc[], double yc[]) {
double mindist = 1E+16, a, b, d;
int i;
for (i = 0; i < maxpoints; i++) {
a = (xc[i] - x) * (xc[i] - x) ;
b = (yc[i] - y) * (yc[i] - y);
d = sqrt(a + b);
if (d < mindist) mindist = d;
}
return(mindist);
}
void doPrecalc (void) {
int x, y, i, r, g, b, cx, cy, diameter = 64;
double mindist, maxdist, distance, c, tx, ty;
for (i = 0; i < maxpoints; i++) {
xcoords[i] = rand() % cdXSize;
ycoords[i] = rand() % cdYSize;
}
mindist = 1E+16;
maxdist = 0;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
tx = abs(x-128); ty = abs(y - 128);
distance = dist (tx, ty, xcoords, ycoords) ;
Distbuffer [x][y] = distance;
if (distance < mindist) mindist = distance;
if (distance > maxdist) maxdist = distance;
}
}
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
c =(Distbuffer [x][y] - mindist) / (maxdist - mindist);
r = (int)(c * 55.);
g = (int)(c * 155.);
b = (int)(c * 255.);
Texture[x][y] = (r << 16) | (g << 8) | b;
}
}
cx = cdXSize; cy = cdYSize;
for (x = 0; x < cdXSize*2; x++) {
for (y = 0; y < cdYSize*2; y++) {
Tangle[x][y] = (int)(atan2(cy - y, cx - x) * 256. / M_PI );
distance = (sqrt((x-cx)*(x-cx) + (y-cy)*(y-cy)));
Tdepth[x][y] = 256. * diameter / distance;
}
}
}
void PintaObjeto (void) {
int x, y, tx, ty;
static double currtime = 0.0;
int sx, sy, slx, sly, k = 0, r, g, b, c;
double d;
currtime += 0.00913;
sx = (int)(256 * 1.0 * currtime);
sy = (int)(256 * 0.25 * currtime);
//Calculate the movement
slx = cdXSize / 2 + (int)(cdXSize / 2 * cos(currtime));
sly = cdYSize / 2 + (int)(cdYSize / 2 * sin(currtime * 3.3));
for (y = 0; y < cdYSize; y++) {
for (x = 0; x < cdXSize; x++, k++) {
tx = (unsigned int)(Tdepth[x + slx][y + sly] + sx) & 255;
ty = (unsigned int)2*(Tangle[x + slx][y + sly] + sy) & 255;
d = (54./Tdepth[x + slx][y + sly]);
c = Texture[tx][ty];
r = (c & (0xFF0000))>>16; g = (c & (0xFF00))>>8; b = c & 0xFF;
r = (int) ((double)r * d); g = (int)((double)g * d); b = (int)((double)b * d);
if (r & 0x1F00) r = 255; if (g & 0x1F00) g = 255; if (b & 0x1F00) b = 255;
*(pMainDIB + k) = b|(g<<8)|(r<<16);
}
}
}
void Inicio (void) {
doPrecalc ();
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HDC bufDIBDC;
static HBITMAP hMainDIB;
HDC hdc ;
PAINTSTRUCT ps ;
static HGDIOBJ hOldDIB=0, hGDITmp;
int bResult;
switch (message)
{
case WM_CHAR :
if (wParam == VK_ESCAPE) {
goto wmDestruimos;
}
return 0 ;
case WM_CREATE:
hdc = GetDC(hWnd);
// Crea un búfer dib para PintaObjeto. pMainDIB es un puntero a él
bufDIBDC = CreateCompatibleDC (hdc);
hMainDIB = CreateDIBSection(hdc, (BITMAPINFO *) &bi, DIB_RGB_COLORS, (void **) &pMainDIB, NULL, 0);
hOldDIB = SelectObject (bufDIBDC, hMainDIB);
ReleaseDC (hWnd, hdc); // Libera device context
Inicio ();
SetTimer (hWnd, cdIdTimer, 20, NULL) ;
return 0 ;
case WM_TIMER :
InvalidateRect (hWnd, NULL, FALSE) ;
return 0 ;
case WM_SIZE :
vdxClient = lParam & 0xFFFF;
vdyClient = lParam >> 0x10;
return 0 ;
case WM_PAINT :
hdc = BeginPaint(hWnd, &ps);
PintaObjeto ();
// bResult = BitBlt(hdc, 0, 0, cdXSize, cdYSize, bufDIBDC, 0, 0, SRCCOPY);
bResult = StretchBlt (hdc, 0, 0, vdxClient, vdyClient, bufDIBDC, 0, 0, cdXSize, cdYSize, SRCCOPY);
EndPaint(hWnd, &ps);
return 0 ;
case WM_DESTROY :
wmDestruimos:
KillTimer (hWnd, cdIdTimer) ;
hGDITmp = SelectObject (bufDIBDC, hOldDIB);
bResult = DeleteDC (bufDIBDC);
bResult = DeleteObject (hMainDIB);
bResult = DestroyWindow (hWnd);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hWnd, message, wParam, lParam) ;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
RECT WRect;
static TCHAR szAppName[] = TEXT ("SWGPTG") ;
HWND hWnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hbrBackground = cdColFondo ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hInstance = GetModuleHandle (NULL) ;
wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(MAIN_ICON)) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
if (!RegisterClass (&wndclass)) {
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
TEXT ("Error"), MB_ICONERROR) ;
return 0 ;
}
SetRect (&WRect, 0, 0, cdXSize, cdYSize);
AdjustWindowRectEx (&WRect, cdVBtnTipo, 0, cdVBarTipo);
WRect.bottom -= WRect.top;
WRect.right -= WRect.left;
WRect.left = (GetSystemMetrics (SM_CXSCREEN) - WRect.right)/2;
WRect.top = (GetSystemMetrics (SM_CYSCREEN) - WRect.bottom) / 3;
hWnd = CreateWindow (szAppName, TEXT ("Tunnel - from Relsoft"),
cdVBtnTipo,//WS_OVERLAPPEDWINDOW,
WRect.left,WRect.top,WRect.right,WRect.bottom,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hWnd, iCmdShow) ;
UpdateWindow (hWnd) ;
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}