Приколы на Си++

Всё, что касается программирования на старых языках или для старых систем

Приколы на Си++

Сообщение StoYazykov » 19 ноя 2025, 18:12

Тут будут приколы на C++ с использованием WinAPI.
Самое тёмное дело - это строки в C

Объектно-ориентированное программирование -- метод изготовления граблей по принципу матрешки.

http://revival.narod.ws

Изображение
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 280
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Наказание для копипастеров

Сообщение StoYazykov » 19 ноя 2025, 18:15

Программка запускается фоном. Если не дай Бог, юзер нажмёт Ctrl+C... сами посмотрите, что будет. А в буфере обмена будет совсем не скопипастенный текст...

 Развернуть: Исходники:
Код: Выделить всё
#include <windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
   HDC hdc = GetDC(NULL);

   while(TRUE) {
      if((GetAsyncKeyState(VK_CONTROL) & 0x8000) && (GetAsyncKeyState('C')  & 0x8000 || GetAsyncKeyState('c')  & 0x8000)) {
         int i, j;
         LONG w=GetSystemMetrics(SM_CXSCREEN), h=GetSystemMetrics(SM_CYSCREEN);
         for(i=0; i<52; i++) {
            BitBlt(hdc, 5, i, w, h, hdc, 0, 5, SRCCOPY);
            Sleep(52);
         }
         MessageBox(NULL, "Эх ты, копипастер, блин!!!", "Эх, ты...", MB_OK | MB_ICONERROR);
         if(!OpenClipboard(NULL)) break;
         EmptyClipboard();
   
         const char str[] = "Хватит копипастить, блин, а!  :-) ";

           HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, strlen(str) + 1);
          if (!hMem) {
              CloseClipboard();
              return false;
          }

          char* pMem = (char*)GlobalLock(hMem);
          strcpy(pMem, str);
          GlobalUnlock(hMem);

          SetClipboardData(CF_TEXT, hMem);
          CloseClipboard();
      }
   }
}
Последний раз редактировалось StoYazykov 22 ноя 2025, 14:53, всего редактировалось 3 раз(а).
Самое тёмное дело - это строки в C

Объектно-ориентированное программирование -- метод изготовления граблей по принципу матрешки.

http://revival.narod.ws

Изображение
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 280
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Re: Приколы на Си++

Сообщение luzga » 21 ноя 2025, 19:16

Программа открывает картинку под названием Picture1.BMP
(картинка должна быть в папке с программой).
Создаётся окно по-региону изображения. Включается таймер.
Окно крутится по-часовой стрелке.
Остановить программу можно нажатием мышки на окне программы.
Изображение
 Развернуть: Текст программы
Код: Выделить всё
#include <windows.h>
#include <stdio.h>

HRGN g_hRgn;
UINT g_nTimer;
#define   TIMER_ID   2025
#define   TIMER_DELAY   50

DWORD Blue=RGB(0,0,255);
DWORD Green=RGB(0,128,0);
DWORD Red=RGB(255,0,0);
DWORD Orange=RGB(240,148,80);
DWORD Violet=RGB(150,129,183);
DWORD Brown=RGB(128,0,0);
DWORD Yellow=RGB(255,255,0);
DWORD Grey=RGB(192,192,192);
DWORD White=RGB(255,255,255);
DWORD Black=RGB(0,0,0);

DWORD ColorText=Green; /* Цвет */

void DrawScene(HWND hWnd)
{
   static int posX, posY, midX, midY, nWidth, nHeight;
   static BOOL bInit;
   if (!bInit)
   {
      bInit=TRUE;

      RECT rect;
      GetWindowRect(hWnd,&rect);
      nWidth=(rect.right-rect.left);
      nHeight=(rect.bottom-rect.top);

      int y=GetSystemMetrics(SM_CYSCREEN);
      posY=y >> 4;
      midY=(y - nHeight) >> 1;
      
      int x=GetSystemMetrics(SM_CXSCREEN);
      posX=x >> 4;
      midX=(x-nWidth) >> 1;
   }

   int x, y, nX, nY;

   static int nAngle=0;
   double fAngle = 0.05;

   __asm
   {
   fld   nAngle   // load angle
   fsincos      // calculate sin/cos
   fild   posX      // load amplitude x
   fmul         // mul by cos
   fistp   nX      // save
   fild   posY      // load amplitude y
   fmul         // mul by sin
   fistp   nY      // save
   fld   nAngle   // load angle
   fadd   fAngle      // increment it
   fstp   nAngle   // and save it

   mov   eax, nY   // center in y
   add   eax, midY
   mov   y, eax

   mov   ebx, nX   // center in x
   add   ebx, midX
   mov   x, ebx
   }

   SetWindowPos(hWnd,HWND_TOPMOST,x,y,nWidth,nHeight,0);
}

BYTE* Get24BitPixels(HBITMAP hBitmap, WORD* wWidth, WORD* wHeight)
{
   BITMAP bm;
   GetObject(hBitmap, sizeof(bm), &bm);

   LPBITMAPINFO pbmiInfo;
   pbmiInfo = (LPBITMAPINFO)&bm;

   /* Get width and height. */
   WORD wBmpWidth, wBmpHeight;
   wBmpWidth = (WORD)pbmiInfo->bmiHeader.biWidth;
   wBmpWidth -= (wBmpWidth%4); /* Width is 4 byte boundary aligned. */
   wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;

   /* Copy to caller width and height parms. */
   *wWidth = wBmpWidth;
   *wHeight = wBmpHeight;

   /* Allocate width * height * 24bits pixels. */
   BYTE* pPixels = new BYTE[wBmpWidth * wBmpHeight * 3];
   if (!pPixels)
      return pPixels;

   /* Get user desktop device context to get pixels from. */
   HDC hDC = GetWindowDC(NULL);

   /* Fill desired structure. */
   BITMAPINFO bmiInfo;
   bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bmiInfo.bmiHeader.biWidth = wBmpWidth;
   bmiInfo.bmiHeader.biHeight = -wBmpHeight;
   bmiInfo.bmiHeader.biPlanes = 1;
   bmiInfo.bmiHeader.biBitCount = 24;
   bmiInfo.bmiHeader.biCompression = BI_RGB;
   bmiInfo.bmiHeader.biSizeImage = wBmpWidth * wBmpHeight * 3;
   bmiInfo.bmiHeader.biXPelsPerMeter = 0;
   bmiInfo.bmiHeader.biYPelsPerMeter = 0;
   bmiInfo.bmiHeader.biClrUsed = 0;
   bmiInfo.bmiHeader.biClrImportant = 0;

   /* Get pixels from the original bitmap converted to 24bits. */
   int nResult = GetDIBits(hDC, hBitmap, 0, wBmpHeight, (LPVOID)pPixels, &bmiInfo, DIB_RGB_COLORS);
   ReleaseDC(NULL, hDC); /* Release the device context. */
   if (!nResult) {
      delete pPixels;
      pPixels = NULL;
   }
   return pPixels;
}

HRGN CreateRegion(HBITMAP hBitmap,
   COLORREF clrTransparent,
   int& nWidth, int& nHeight)
{
   BYTE jTranspR = GetRValue(clrTransparent);
   BYTE jTranspG = GetGValue(clrTransparent);
   BYTE jTranspB = GetBValue(clrTransparent);

   /* Bitmap width and height. */
   WORD wBmpWidth, wBmpHeight;

   /* The final region and a temporary region. */
   HRGN hRgn, hTmpRgn;
   nWidth = nHeight = 0;

   /* 24bit pixels from the bitmap. */
   BYTE* pPixels = Get24BitPixels(hBitmap, &wBmpWidth, &wBmpHeight);
   if (!pPixels)
      return NULL;

   nWidth = wBmpWidth;
   nHeight = wBmpHeight;

   /* Create our working region. */
   hRgn = CreateRectRgn(0, 0, wBmpWidth, wBmpHeight);
   if (!hRgn) {
      delete pPixels;
      return NULL;
   }

   /* Scan the bitmap. */
   DWORD p=0;
   for (WORD y=0; y<wBmpHeight; ++y)
   {
      for (WORD x=0; x<wBmpWidth; ++x)
      {
         BYTE jRed = pPixels[p+2];
         BYTE jGreen = pPixels[p+1];
         BYTE jBlue = pPixels[p+0];

         if (jRed == jTranspR &&
            jGreen == jTranspG &&
            jBlue == jTranspB)
         {
            /* Remove transparent color from region. */
            hTmpRgn = CreateRectRgn(x, y, x+1, y+1);
            CombineRgn(hRgn, hRgn, hTmpRgn, RGN_DIFF);
            DeleteObject(hTmpRgn);
         }

         /* Next pixel. */
         p += 3;
      } /* End "for (WORD x=0; x<wBmpWidth; ++x)" */
      
   } /* End "for()" */
   delete pPixels;
   return hRgn;
}

void OnTimer(HWND hWnd, WPARAM wParam) {
   if (TIMER_ID==wParam)
      DrawScene(hWnd);
}

BOOL OnCreate(LPCREATESTRUCT lpCreateStruct) {
   HWND hWnd=lpCreateStruct->hwndParent;
   /* Set the timer for one-second intervals. */
   g_nTimer=SetTimer(hWnd,TIMER_ID,TIMER_DELAY,NULL);
   if (!g_nTimer)
   {
      MessageBox(hWnd,"Cannot SetTimer","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      return -1;
   }
   return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
   //static int X, Y;
   LRESULT retval=0;
   LPCREATESTRUCT lpCreateStruct;
   switch (uMsg) {
   case WM_CREATE: {
      lpCreateStruct=reinterpret_cast<LPCREATESTRUCT>(lParam);
      lpCreateStruct->hwndParent=hWnd;
   }
   return OnCreate(lpCreateStruct);
   case WM_TIMER:
      OnTimer(hWnd,wParam);
      break;
   /*case WM_MOUSEMOVE:
   if (wParam & MK_RBUTTON || wParam & MK_LBUTTON) {
      RECT rect;
      GetWindowRect(hWnd,&rect);
      MoveWindow(hWnd,rect.left+LOWORD(lParam)-X,rect.top+HIWORD(lParam)-Y,rect.right-rect.left,rect.bottom-rect.top,TRUE);
   } else {
      X=LOWORD(lParam);
      Y=HIWORD(lParam);
   }
   break;*/
   case WM_SIZE:
      SetWindowRgn(hWnd, g_hRgn, TRUE);
      break;
   case WM_LBUTTONDOWN:
   //case WM_LBUTTONDBLCLK:
      SendMessage(hWnd,WM_CLOSE,0,0);
      break;
   case WM_CLOSE:
      DestroyWindow(hWnd);
      break;
   case WM_DESTROY:
      if (g_nTimer) {
         KillTimer(hWnd,g_nTimer);
         g_nTimer=NULL;
      }
      PostQuitMessage(0);
      break;
   default:
      retval=DefWindowProc(hWnd,uMsg,wParam,lParam);
   } /* End "switch (uMsg)" */
   return retval;
}

/*
* Entry point.
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
   HBITMAP hbitmap = (HBITMAP)LoadImage(NULL,
      "Picture1.bmp", IMAGE_BITMAP,
      0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
   if (!hbitmap) {
      MessageBox(HWND_DESKTOP,"Cannot load bitmap","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(1);
   }

   int nWidth, nHeight;
   COLORREF clrTransparent = RGB(255,255,255);
   g_hRgn = CreateRegion(hbitmap,
      clrTransparent, nWidth, nHeight);
   if (!g_hRgn)
   {
      MessageBox(HWND_DESKTOP,"Cannot CreateRegion","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(2);
   }

   /* Create brush. */
   LOGBRUSH brush;
   brush.lbStyle=BS_SOLID;
   //brush.lbColor=RGB(0,255,255);
   brush.lbColor=ColorText;
   brush.lbHatch=HS_BDIAGONAL;
   HBRUSH hBrush=CreateBrushIndirect(&brush);

   WNDCLASSEX wcex={sizeof(WNDCLASSEX),
   CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS,
   WndProc,0,0,hInstance,
   LoadIcon(NULL,IDI_APPLICATION),
   LoadCursor(NULL,IDC_ARROW),
   hBrush,NULL,"wnd_sp4s1",NULL,};

   ATOM Atom=RegisterClassEx(&wcex);
   if (!Atom) {
      Atom=RegisterClass((LPWNDCLASS)&wcex.style);
      if (!Atom) {
         MessageBox(HWND_DESKTOP,"Cannot register class","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
         ExitProcess(3);
      }
   }
   DWORD dwExStyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
   DWORD dwStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_THICKFRAME;
   /* Window position center desktop. */   
   HWND hWnd = CreateWindowEx(dwExStyle,
   MAKEINTATOM(Atom), "SOS", dwStyle,
   ((GetSystemMetrics(SM_CXSCREEN)-nWidth)/2),
   ((GetSystemMetrics(SM_CYSCREEN)-nHeight)/2),
   nWidth, nHeight,
   HWND_DESKTOP, NULL, hInstance, NULL);
   if (!hWnd) {
      MessageBox(hWnd,"Cannot create window","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(4);
   }
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   MSG msg;
   while(GetMessage(&msg, NULL, 0, 0)>0) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return (int)msg.wParam;
}

Собрать можно Borland C++ версии 5.x или Visual Studio 6.0 и версией выше.
Вложения
Spasi.zip
(40.18 Кб) Скачиваний: 269
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение luzga » 21 ноя 2025, 19:26

StoYazykov писал(а):Если не дай Бог, юзер нажмёт Ctrl+C... сами посмотрите, что будет.

Пугаете, молодой человек :D . Вообще лучше рассказывать, что оно делает, а то действительно - боязно. Потом. Нет уже собранной, а собирать как-то ленно...

P.S.
Первый прикол делает следующее.
При нажатии Ctrl+C - cм. картинку
 Развернуть: Рабочий стол поплыл
Изображение

Я добавил Sleep(), чтобы cpu не расходовался, ну-и файлы для сборки.
Собирается Borland C и VC. В пакете имеется собранный EXE.
Вложения
Prikol_01.zip
(33.1 Кб) Скачиваний: 249
Последний раз редактировалось luzga 22 ноя 2025, 13:36, всего редактировалось 1 раз.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение StoYazykov » 22 ноя 2025, 14:52

luzga, а как это сделано? Картинка bmp, но притом... прозрачная!
Самое тёмное дело - это строки в C

Объектно-ориентированное программирование -- метод изготовления граблей по принципу матрешки.

http://revival.narod.ws

Изображение
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 280
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Re: Приколы на Си++

Сообщение luzga » 22 ноя 2025, 15:41

StoYazykov писал(а):luzga, а как это сделано? Картинка bmp, но притом... прозрачная!

Функция HRGN CreateRegion(HBITMAP hBitmap,
COLORREF clrTransparent,
int& nWidth,
int& nHeight)
Принимает картинку (hBitmap) и цвет (clrTransparent) который игнорируется при копировании байт. Цвет этот - фон на котором нарисован пейзаж.
В данном случае игнорируется белый цвет - это RGB(255,255,255).
Если рисунок будет нарисован на любом другом фоне, то окно программы будет прямоугольным т.е. по-размеру рисунка.
После копировании байт, функция возвращает силуэт (регион) картинки (HRGN) и размер изображения, это ширина (nWidth) и высота (nHeight).
Теперь, с помощью функции Windows SetWindowRgn() создаём окно
программы.
Таким образом создаются разнообразные скины, например Winamp.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение luzga » 24 ноя 2025, 18:19

Птица летит по Рабочему столу.
Изображение
Нажатие на спрайте мышкой (левой или правой) клавишей - выход.
Программа завершается после достижения движения - правой стороны экрана!
 Развернуть: Исходный код программы
Код: Выделить всё
/* WinMain.cpp
*
* Нажатие на спрайте мышкой - выход.
*/

#include <windows.h>

#define FLY_SPEED 5 /* Скорость движения. */

void LoadFrame(HWND hWnd, char* svFilename)
{
   char svBuff[512];

   HANDLE hFile=CreateFile(svFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
   if (INVALID_HANDLE_VALUE==hFile) {
      wsprintf(svBuff,"Cannot open\n\"%s\"",svFilename);
      MessageBox(hWnd,svBuff,"Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(1);
   }

   DWORD dwFileSize=GetFileSize(hFile,NULL);
   if (!dwFileSize) {
      wsprintf(svBuff,"Failed file size\n\"%s\"",svFilename);
      MessageBox(hWnd,svBuff,"Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(3);
   }

   BYTE* pBuffer=(BYTE*)GlobalAlloc(GMEM_FIXED,dwFileSize+1);
   if (!pBuffer) {
      MessageBox(hWnd,"Failed GlobalAlloc","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(3);
   }

   DWORD BytesRead;
   ReadFile(hFile,pBuffer,dwFileSize,&BytesRead,NULL);
   CloseHandle(hFile);
   if (!BytesRead) {
      wsprintf(svBuff,"Failed read file\n\"%s\"",svFilename);
      MessageBox(hWnd,svBuff,"Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(3);
   }

   int nDestWidth=*(DWORD*)&pBuffer[18];
   int nDestHeight=*(DWORD*)&pBuffer[22];

   BYTE* pBits=(BYTE*)(pBuffer+1078);
   BITMAPINFO* pBitsInfo=(BITMAPINFO*)(pBuffer+14);
   int pImage=(int)pBuffer+1078;

   int n,nStop,nRightRect,nLeftRect,nTopRect;
   nTopRect=nDestHeight;
   nStop=nDestHeight;

   char svPtr,svPtr2;
   HRGN hrgnDest,hrgnSrc1;
   hrgnDest=CreateRectRgn(0,0,0,0);

   while (nStop!=1) {
      nRightRect=0;
      n=nDestWidth+pImage;
      while (pImage!=n) {
         svPtr=*(BYTE*)pImage++;
         ++nRightRect;
         if (svPtr) {
            nLeftRect=nRightRect;
            while (pImage!=n) {
               svPtr2=*(BYTE*)pImage++;
               ++nRightRect;
               if (!svPtr2)
                  __asm jmp CREATE_RGN;
            }
            ++nRightRect;
CREATE_RGN:
            hrgnSrc1=CreateRectRgn(nLeftRect-1,nTopRect-1,nRightRect-1,nTopRect);
            CombineRgn(hrgnDest,hrgnSrc1,hrgnDest,RGN_OR);
            DeleteObject(hrgnSrc1);
         }
      }
      ++pImage;
      --nTopRect;
      --nStop;
   }   
   SetWindowRgn(hWnd,hrgnDest,1);

   static int x,y,max_x;
   if (!max_x) {
      int t=GetSystemMetrics(SM_CYSCREEN);
      y=(t-nDestHeight)>>1;
      max_x=GetSystemMetrics(SM_CXSCREEN);
   }
   x += FLY_SPEED;
   if (x>max_x)
      ExitProcess(0);

   SetWindowPos(hWnd,HWND_TOPMOST,
      x,y,nDestWidth,nDestHeight,0);

   HDC hDC=GetDC(hWnd);
   if (hDC) {
      StretchDIBits(hDC,0,0,
         nDestWidth,
         nDestHeight,
         0,
         0,
         nDestWidth,
         nDestHeight,
         pBits,
         pBitsInfo,
         DIB_RGB_COLORS,
         SRCCOPY);

      ReleaseDC(hWnd,hDC);
   }
   GlobalFree(pBuffer);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   LRESULT retval=0;
   switch (uMsg) {   
      case WM_LBUTTONDOWN:
      case WM_RBUTTONDOWN:
         SendMessage(hWnd,WM_CLOSE,0,0);
         break;
      case WM_DESTROY:
         PostQuitMessage(0);
         break;
      default:
         retval=DefWindowProc(hWnd,uMsg,wParam,lParam);
   }
   return retval;
}

/*
* Entry point
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
   WNDCLASSEX wcex={sizeof(WNDCLASSEX),
   CS_VREDRAW|CS_HREDRAW,
   WndProc,0,0,hInstance,
   LoadIcon(NULL,IDI_APPLICATION),
   LoadCursor(NULL,IDC_ARROW),
   (HBRUSH)(COLOR_WINDOW+1),
   NULL,"wnd_B1rd",NULL,};

   ATOM Atom=RegisterClassEx(&wcex);
   if(!Atom) {
      Atom=RegisterClass((LPWNDCLASS)&wcex.style);
      if (!Atom) {
         MessageBox(HWND_DESKTOP,"Cannot register class","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
         ExitProcess(1);
      }
   }

   DWORD dwExStyle=WS_EX_TOPMOST|WS_EX_TOOLWINDOW;
   DWORD dwStyle=WS_VISIBLE|WS_POPUP;
   HWND hWnd=CreateWindowEx(dwExStyle,
      MAKEINTATOM(Atom),"Bird",dwStyle,
      0,0,0,0,
      HWND_DESKTOP,NULL,hInstance,NULL);
   if (!hWnd) {
      MessageBox(hWnd,"Cannot create window","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(2);
   }
   ShowWindow(hWnd,nCmdShow);
   UpdateWindow(hWnd);

   MSG msg;
   DWORD dwDelay,dwFrame;
   dwDelay=dwFrame=0;
   
   while (1) {
      PeekMessage(&msg,0,0,0,PM_REMOVE);
      if (WM_QUIT==msg.message)
         break;

      DWORD dwTick=GetTickCount();
      if (dwTick-dwDelay>=70)
      {
         dwDelay=dwTick;
         switch (dwFrame) {
         case 0:
         LoadFrame(hWnd,"Bird\\Bird_00.bmp");
         dwFrame=1;
         break;
         case 1:
         LoadFrame(hWnd,"Bird\\Bird_01.bmp");
         dwFrame=2;
         break;
         case 2:
         LoadFrame(hWnd,"Bird\\Bird_02.bmp");
         dwFrame=3;
         break;
         case 3:
         LoadFrame(hWnd,"Bird\\Bird_03.bmp");
         dwFrame=4;
         break;
         case 4:
         LoadFrame(hWnd,"Bird\\Bird_04.bmp");
         dwFrame=5;
         break;
         case 5:
         LoadFrame(hWnd,"Bird\\Bird_05.bmp");
         dwFrame=6;
         break;
         case 6:
         LoadFrame(hWnd,"Bird\\Bird_06.bmp");
         dwFrame=0;
         }
      }
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      Sleep(20); // Give up!
   }
   return (int)msg.wParam;
}

Собрать программу можно как старыми так и новыми компиляторами.
В приложенном пакете имеется собранная программа.
Вложения
Bird.zip
(21.64 Кб) Скачиваний: 252
Последний раз редактировалось luzga 24 ноя 2025, 18:22, всего редактировалось 1 раз.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение StoYazykov » 24 ноя 2025, 20:50

luzga писал(а):Птица летит по Рабочему столу.
Изображение
Нажатие на спрайте мышкой (левой или правой) клавишей - выход.
Программа завершается после достижения движения - правой стороны экрана!
 Развернуть: Исходный код программы
Код: Выделить всё
/* WinMain.cpp
*
* Нажатие на спрайте мышкой - выход.
*/

#include <windows.h>

#define FLY_SPEED 5 /* Скорость движения. */

void LoadFrame(HWND hWnd, char* svFilename)
{
   char svBuff[512];

   HANDLE hFile=CreateFile(svFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
   if (INVALID_HANDLE_VALUE==hFile) {
      wsprintf(svBuff,"Cannot open\n\"%s\"",svFilename);
      MessageBox(hWnd,svBuff,"Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(1);
   }

   DWORD dwFileSize=GetFileSize(hFile,NULL);
   if (!dwFileSize) {
      wsprintf(svBuff,"Failed file size\n\"%s\"",svFilename);
      MessageBox(hWnd,svBuff,"Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(3);
   }

   BYTE* pBuffer=(BYTE*)GlobalAlloc(GMEM_FIXED,dwFileSize+1);
   if (!pBuffer) {
      MessageBox(hWnd,"Failed GlobalAlloc","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(3);
   }

   DWORD BytesRead;
   ReadFile(hFile,pBuffer,dwFileSize,&BytesRead,NULL);
   CloseHandle(hFile);
   if (!BytesRead) {
      wsprintf(svBuff,"Failed read file\n\"%s\"",svFilename);
      MessageBox(hWnd,svBuff,"Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(3);
   }

   int nDestWidth=*(DWORD*)&pBuffer[18];
   int nDestHeight=*(DWORD*)&pBuffer[22];

   BYTE* pBits=(BYTE*)(pBuffer+1078);
   BITMAPINFO* pBitsInfo=(BITMAPINFO*)(pBuffer+14);
   int pImage=(int)pBuffer+1078;

   int n,nStop,nRightRect,nLeftRect,nTopRect;
   nTopRect=nDestHeight;
   nStop=nDestHeight;

   char svPtr,svPtr2;
   HRGN hrgnDest,hrgnSrc1;
   hrgnDest=CreateRectRgn(0,0,0,0);

   while (nStop!=1) {
      nRightRect=0;
      n=nDestWidth+pImage;
      while (pImage!=n) {
         svPtr=*(BYTE*)pImage++;
         ++nRightRect;
         if (svPtr) {
            nLeftRect=nRightRect;
            while (pImage!=n) {
               svPtr2=*(BYTE*)pImage++;
               ++nRightRect;
               if (!svPtr2)
                  __asm jmp CREATE_RGN;
            }
            ++nRightRect;
CREATE_RGN:
            hrgnSrc1=CreateRectRgn(nLeftRect-1,nTopRect-1,nRightRect-1,nTopRect);
            CombineRgn(hrgnDest,hrgnSrc1,hrgnDest,RGN_OR);
            DeleteObject(hrgnSrc1);
         }
      }
      ++pImage;
      --nTopRect;
      --nStop;
   }   
   SetWindowRgn(hWnd,hrgnDest,1);

   static int x,y,max_x;
   if (!max_x) {
      int t=GetSystemMetrics(SM_CYSCREEN);
      y=(t-nDestHeight)>>1;
      max_x=GetSystemMetrics(SM_CXSCREEN);
   }
   x += FLY_SPEED;
   if (x>max_x)
      ExitProcess(0);

   SetWindowPos(hWnd,HWND_TOPMOST,
      x,y,nDestWidth,nDestHeight,0);

   HDC hDC=GetDC(hWnd);
   if (hDC) {
      StretchDIBits(hDC,0,0,
         nDestWidth,
         nDestHeight,
         0,
         0,
         nDestWidth,
         nDestHeight,
         pBits,
         pBitsInfo,
         DIB_RGB_COLORS,
         SRCCOPY);

      ReleaseDC(hWnd,hDC);
   }
   GlobalFree(pBuffer);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   LRESULT retval=0;
   switch (uMsg) {   
      case WM_LBUTTONDOWN:
      case WM_RBUTTONDOWN:
         SendMessage(hWnd,WM_CLOSE,0,0);
         break;
      case WM_DESTROY:
         PostQuitMessage(0);
         break;
      default:
         retval=DefWindowProc(hWnd,uMsg,wParam,lParam);
   }
   return retval;
}

/*
* Entry point
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
   WNDCLASSEX wcex={sizeof(WNDCLASSEX),
   CS_VREDRAW|CS_HREDRAW,
   WndProc,0,0,hInstance,
   LoadIcon(NULL,IDI_APPLICATION),
   LoadCursor(NULL,IDC_ARROW),
   (HBRUSH)(COLOR_WINDOW+1),
   NULL,"wnd_B1rd",NULL,};

   ATOM Atom=RegisterClassEx(&wcex);
   if(!Atom) {
      Atom=RegisterClass((LPWNDCLASS)&wcex.style);
      if (!Atom) {
         MessageBox(HWND_DESKTOP,"Cannot register class","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
         ExitProcess(1);
      }
   }

   DWORD dwExStyle=WS_EX_TOPMOST|WS_EX_TOOLWINDOW;
   DWORD dwStyle=WS_VISIBLE|WS_POPUP;
   HWND hWnd=CreateWindowEx(dwExStyle,
      MAKEINTATOM(Atom),"Bird",dwStyle,
      0,0,0,0,
      HWND_DESKTOP,NULL,hInstance,NULL);
   if (!hWnd) {
      MessageBox(hWnd,"Cannot create window","Error",MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_SYSTEMMODAL);
      ExitProcess(2);
   }
   ShowWindow(hWnd,nCmdShow);
   UpdateWindow(hWnd);

   MSG msg;
   DWORD dwDelay,dwFrame;
   dwDelay=dwFrame=0;
   
   while (1) {
      PeekMessage(&msg,0,0,0,PM_REMOVE);
      if (WM_QUIT==msg.message)
         break;

      DWORD dwTick=GetTickCount();
      if (dwTick-dwDelay>=70)
      {
         dwDelay=dwTick;
         switch (dwFrame) {
         case 0:
         LoadFrame(hWnd,"Bird\\Bird_00.bmp");
         dwFrame=1;
         break;
         case 1:
         LoadFrame(hWnd,"Bird\\Bird_01.bmp");
         dwFrame=2;
         break;
         case 2:
         LoadFrame(hWnd,"Bird\\Bird_02.bmp");
         dwFrame=3;
         break;
         case 3:
         LoadFrame(hWnd,"Bird\\Bird_03.bmp");
         dwFrame=4;
         break;
         case 4:
         LoadFrame(hWnd,"Bird\\Bird_04.bmp");
         dwFrame=5;
         break;
         case 5:
         LoadFrame(hWnd,"Bird\\Bird_05.bmp");
         dwFrame=6;
         break;
         case 6:
         LoadFrame(hWnd,"Bird\\Bird_06.bmp");
         dwFrame=0;
         }
      }
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      Sleep(20); // Give up!
   }
   return (int)msg.wParam;
}

Собрать программу можно как старыми так и новыми компиляторами.
В приложенном пакете имеется собранная программа.


Прикольная птичка)
Кстати, можно сделать и стаю.
Вложения
birds.bmp
birds.bmp (1.62 Мб) Просмотров: 7203
Самое тёмное дело - это строки в C

Объектно-ориентированное программирование -- метод изготовления граблей по принципу матрешки.

http://revival.narod.ws

Изображение
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 280
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Re: Приколы на Си++

Сообщение september2489 » 24 ноя 2025, 21:54

luzga писал(а):Птица летит по Рабочему столу.

Раньше с овечками такая программа была. Можно и ваших птиц докрутить до такого же уровня - получится прикольная программа в стиле начала нулевых.
Аватара пользователя
september2489
Мастер Даунгрейда
 
Сообщения: 479
Зарегистрирован: 16 дек 2024, 21:52
Железо: Lenovo ThinkPad T60p, Asus A9Rp

Re: Приколы на Си++

Сообщение luzga » 25 ноя 2025, 07:12

september2489 писал(а):Раньше с овечками такая программа была.

Мне встречалась с девчёнкой в бикини разгуливающей взад вперёд (кажется) или в зависимости от курсора.
september2489 писал(а):Можно и ваших птиц докрутить до такого же уровня

Не вопрос, но лично мне - это неинтересно, вот - кто-то другой на этой основе пусть и займётся :D
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение luzga » 05 дек 2025, 17:20

Прикол Скелетон. Программа для MS-Dos.
Показывает картинку. Масштабирует.

При запуске без параметров, будет пытаться
открыть файл Skeleton.bmp

Картинка должна быть 256-ти цветная, размеры 320 на 200.
Запуск своей картинки: Skeleton Picture.BMP

Рабочие клавиши: Q - Выйти.
Стрелки Вверх, Вниз - увеличить, уменьшить.
Клавиши Плюс, Минус - медленнее, быстрее.
R - сброс.
Изображение
Внимание: программа корректно работает только в Dos, Windows 9x - XP.
В DosBox - не работает (тормозит)!
 Развернуть: Исходный код
Код: Выделить всё
// Skeleton.cpp
//
// Draw bitmap 320 x 200 256 colors. Scaling. Rotate.
// Work key:
// Q - Exit program.
// Arrows Up, Down, key Plus, Minus.
// R - reset.

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#include <memory.h>
#include <math.h>
#pragma warn -sig // Suppress warn msg Conversion may lose significant digits.

typedef unsigned char byte;
byte far* vgaScreen=(byte far*)0xA0000000L; // This points to video memory.
char* g_szFilename="Skeleton.bmp"; // Default filename.

void SetVideoMode(byte mode)
{
   union REGS inregs,outregs;
   inregs.h.ah=0;
   inregs.h.al=mode;
   int86(0x10,&inregs,&outregs);
}

/*
* Entry point.
*/
void main(unsigned int argc, char* argv[])
{
   char* fname=g_szFilename; // Default filename.
   if (argc>=2) // If we have enought arguments.
      fname=argv[1];

   FILE* stream=fopen(fname,"rb");
   if (!stream) {
      printf("%s cant open file.\n",fname);
      system("pause>nul"); // Press Any key...
      exit(1);
   }

   // Check picture format.
   if ('B'!=fgetc(stream) || 'M'!=fgetc(stream)) {
      fclose(stream);
      printf("%s is not a bitmap file.\n",fname);
      system("pause>nul");
      exit(1);
   }

   int nWidth,nHeight; // Check picture size.
   fseek(stream,18,SEEK_SET);
   fread(&nWidth,sizeof(int),1,stream);
   fseek(stream,22,SEEK_SET);
   fread(&nHeight,sizeof(int),1,stream);
   if (nWidth>320 || nHeight>200) {
      fclose(stream);
      printf("%s is picture format not supported.\n",fname);
      system("pause>nul");
      exit(1);
   }

   int nColors; // Check dept colors.
   fseek(stream,28,SEEK_SET);
   fread(&nColors,sizeof(int),1,stream);
   if (nColors>8) {
      fclose(stream);
      printf("%s is bitmap dept colors need 256 (8BPP).\n",fname);
      system("pause>nul");
      exit(1);
   }

   // Allocate screen buffer memory.
   byte far* screen=(byte far*)farmalloc(64000U);
   if (!screen) {
      printf("Error allocating screen memory.\n");
      exit(1);
   }

   byte far* scrImage=(byte far*)farmalloc(64000U);
   if (!scrImage) {
      printf("Error allocating screen memory #2.\n");
      system("pause>nul");
      exit(1);
   }

   SetVideoMode(0x13); // Set video mode to graphics mode 320X200X256
   outportb(0x3C2,0xE3); // Set square aspect ratio.

   fseek(stream,54,SEEK_SET); // Set pointer to palette.
   // This sets a DAC register to a specific red green blue value.
   byte palBuff[256][4];
   fread(&palBuff,1024,1,stream);
   for (int i=0;i<256;++i) {
      outportb(0x3C8,i);
      outportb(0x3C9,palBuff[i][2]>>2);
      outportb(0x3C9,palBuff[i][1]>>2);
      outportb(0x3C9,palBuff[i][0]>>2);
   }

   long nCount=64000U; // Set pointer to data and load.
   while (nCount>0)
      scrImage[--nCount]=getc(stream);
   fclose(stream);

   for (int i=0;i<nHeight;++i)
      for (int j=0;j<nWidth;++j)
         vgaScreen[((i<<8)+(i<<6))+(nWidth-j)]=scrImage[((i<<8)+(i<<6))+j];
   _fmemset(vgaScreen,0,64000U);

   // Initialize fixed point sin, cos tables.
   static long cosTab[256];
   static long sinTab[256];
   for (int i=0;i<256;++i) {
      cosTab[i]=cos((6.28/256)*i)*1024;
      sinTab[i]=sin((6.28/256)*i)*1024;
   }

   // Initialize y offset table.
   static int yTab[200];
   for (int i=0;i<200;++i)
      yTab[i]=i*320;

   int nAngle,nDone,nScale=800;
   nAngle=nDone=nCount=0;
   int nDelay=20;
   int ch=0;
   while (ch != 'q' && ch != 'Q') // Q - Exit program
   {
      if (kbhit())
      {
         ch = getch();
         if (ch == 72) // Arrow Up
         {
            if (nScale <= 0)
               nScale = 0;
            else
               nScale -= 10;
         }
         if (ch == 80) // Arrow Down
         {
            if (nScale >= 7000)
               nScale = 7000;
            else
               nScale += 10;
         }
         if (ch == '+' || ch == '=') // Plus +
         {
            if (nDelay >= 100)
               nDelay = 100;
            else
               nDelay += 1;
         }
         if (ch == '-') // Minus -
         {
            if (nDelay <= 1)
               nDelay = 1;
            else
               nDelay -= 1;
         }
         if (ch == 'r' || ch == 'R') // Reset
         {
            nScale = 800;
            nDelay = 20;
         }
      }

      switch (nDone)
      {
      case 0:
         if (nCount>=50)
            nDone = 1;
         ++nCount;
         nAngle = nCount;
      break;
      case 1:
         if (nCount<=1)
            nDone = 2;
         --nCount;
         nAngle = nCount;
      break;
      case 2:
         if (nCount>=50)
            nDone = 3;
         ++nCount;
         nAngle = 255-nCount;
      break;
      case 3:
         if (nCount<=1)
            nDone = 0;
         --nCount;
         nAngle = 255-nCount;
      }
      long c=cosTab[nAngle];
      long s=sinTab[nAngle];

      for (int y=-100; y<100; ++y)
      {
         long ys=(y*s>>10);
         long yc=(y*c>>10);
         for (int x=-160; x<160; ++x)
         {
            // x = cos(x)-sin(y) * nScale;
            int xT = ((((x*c)>>10)-ys)*nScale)>>10;
            // y = sin(x)+cos(y) * nScale;
            int yT = ((((x*s)>>10)+yc)*nScale)>>10;
            if (xT > -160 && xT < 160 && yT > -100 && yT < 100)
            {
               screen[(x+160)+yTab[(y+100)]]=
                  scrImage[(xT+160)+yTab[yT+100]];
            }
         }
      }
      _fmemcpy(vgaScreen,screen,64000U);
      _fmemset(screen,0,64000U);
      delay(nDelay);
   }

   // Clean up.
   if (screen)
      farfree(screen);
   if (scrImage)
      farfree(scrImage);
   SetVideoMode(0x03); // Return to text mode.
}

P.S. Отредактировано.
Исправлена ошибка в тексте (клавиша сброса R).
Вложения
Skeleton.zip
(51.09 Кб) Скачиваний: 252
Последний раз редактировалось luzga 06 дек 2025, 06:21, всего редактировалось 2 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение StoYazykov » 07 дек 2025, 11:50

luzga писал(а):
StoYazykov писал(а):luzga, а как это сделано? Картинка bmp, но притом... прозрачная!

Функция HRGN CreateRegion(HBITMAP hBitmap,
COLORREF clrTransparent,
int& nWidth,
int& nHeight)
Принимает картинку (hBitmap) и цвет (clrTransparent) который игнорируется при копировании байт. Цвет этот - фон на котором нарисован пейзаж.
В данном случае игнорируется белый цвет - это RGB(255,255,255).
Если рисунок будет нарисован на любом другом фоне, то окно программы будет прямоугольным т.е. по-размеру рисунка.
После копировании байт, функция возвращает силуэт (регион) картинки (HRGN) и размер изображения, это ширина (nWidth) и высота (nHeight).
Теперь, с помощью функции Windows SetWindowRgn() создаём окно
программы.
Таким образом создаются разнообразные скины, например Winamp.


luzga, а на такое окно можно добавить стандартную кнопку через
Код: Выделить всё
CreateWindow("button","Текст кнопки",WS_CHILD|BS_PUSHBUTTON|WS_VISIBLE,
    5,5,100,20,hw,(HMENU)ID_BUTTON,NULL,NULL);

или надо свою рисовать?
Последний раз редактировалось StoYazykov 07 дек 2025, 11:52, всего редактировалось 1 раз.
Самое тёмное дело - это строки в C

Объектно-ориентированное программирование -- метод изготовления граблей по принципу матрешки.

http://revival.narod.ws

Изображение
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 280
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Re: Приколы на Си++

Сообщение luzga » 07 дек 2025, 14:59

StoYazykov писал(а):а на такое окно можно добавить стандартную кнопку

Нет.

Учиться. Учиться и Учиться.
В.И.Ленин
Последний раз редактировалось luzga 08 дек 2025, 18:51, всего редактировалось 4 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

Re: Приколы на Си++

Сообщение StoYazykov » 08 дек 2025, 17:01

Да нет, luzga, я не про простое окно. Можно ли, например, на вашу птицу (с точки зрения WinAPI - это же тоже окно, по сути!) добавить стандартную кнопку? Или надо свою городить?
Самое тёмное дело - это строки в C

Объектно-ориентированное программирование -- метод изготовления граблей по принципу матрешки.

http://revival.narod.ws

Изображение
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 280
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Re: Приколы на Си++

Сообщение luzga » 08 дек 2025, 18:50

Выводит логотип сайта Old-Dos.ru
на горизонтальном звёздном поле.
Изображение
DosBox не мчит звёзды - просто загораются. Записать не удалось.
Оценит, только обладатель реального железа!
 Развернуть: исходняк
Код: Выделить всё
// ODLogo.cpp
//
// Выводит логотип сайта Old-Dos.ru
// на горизонтальном звёздном поле.

#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <process.h>
#include "StarsH.h"
#pragma warn -sig // Suppress warn msg Conversion may lose significant digits.

typedef unsigned char byte;
byte far* vgaScreen=(byte far*)0xA0000000L; // This points to video memory.
char* g_szFilename="ODLogo.bmp";
long g_nSize;
unsigned int* pTable;

unsigned int* YPosChart;
#define ScreenWidth 320
#define ScreenHeight 200
#define VLevel1 1
#define VLevel2 2
#define VLevel3 3
#define VLevel4 4
#define XPos    0
#define YPos   1
#define Old_Pos   2

unsigned int CheckCoord(unsigned int nMatch)
{
   for (int i=0;i<g_nSize;++i) {
      if (nMatch==pTable[i]) {
         return 1;
      }
   }
   return 0;
}

void display_stars(void)
{
   int star_ref; // Which star out of the 120 that we are on.
   unsigned int ypost; // For the Ypostion calculations.
   for (star_ref=0;star_ref<40;++star_ref) // 4th level, do 40 stars
   {
      *((vgaScreen)+star[star_ref][Old_Pos])=0;
      ypost=star[star_ref][YPos]; // Grab the Y-Position of current star.

      ypost=ypost+ypost;
      /* Double it, because in our look up chart, we have ints, and
      everyone knows that ints are two bytes, so line 100 would be
      200 lines down, so we double it. */

      ypost=*(YPosChart+ypost);
      /* Actually grab the value, and store it in ypost. */

      star[star_ref][XPos]+=VLevel1;
      /* Add the velocity of the level, to the current x-position. */

      if (star[star_ref][XPos] > ScreenWidth)
         star[star_ref][XPos]-=ScreenWidth;
      /* Checks to make sure it dont go beyond the range of memory,
      by subtracting 320 when it goes above 320, there by moving it
      back to the beginning of the line. */

      ypost+=star[star_ref][XPos];
      // Add the new xposition to the y position,
      // giving us our new offset.

      if (!CheckCoord(ypost)) // Check coordinate.
      {
         *((vgaScreen)+ypost)=22;
         /* Draw it a pretty dark shade of grey, 22-30 are the
         colors I used.  Dreaden used a custom palette, but I figured
         what the heck, I will use the default. */
         star[star_ref][Old_Pos]=ypost;
         // Stores the position so we can erase it next time.
      }
   }

   for (star_ref=40;star_ref<70;++star_ref) // Third level, thirty stars.
   {   
      *((vgaScreen)+star[star_ref][Old_Pos])=0;
      ypost=star[star_ref][YPos];
      ypost=ypost+ypost;
      ypost=*(YPosChart+ypost);

      star[star_ref][XPos]+=VLevel2; // Only thing that changes.

      if (star[star_ref][XPos] > ScreenWidth)
         star[star_ref][XPos]-=ScreenWidth;

      ypost+=star[star_ref][XPos];

      if (!CheckCoord(ypost)) // Check coordinate.
      {
         *((vgaScreen)+ypost)=24; // A little bit brighter.
         star[star_ref][Old_Pos]=ypost;
      }
   }

   for (star_ref=70;star_ref<90;++star_ref) // Second level, 20 stars.
   {   
      *((vgaScreen)+star[star_ref][Old_Pos])=0;
      ypost=star[star_ref][YPos];
      ypost=ypost+ypost;
      ypost=*(YPosChart+ypost);

      star[star_ref][XPos]+=VLevel3; // And Faster.

      if (star[star_ref][XPos] > ScreenWidth)
         star[star_ref][XPos]-=ScreenWidth;

      ypost+=star[star_ref][XPos];

      if (!CheckCoord(ypost)) // Check coordinate.
      {
         *((vgaScreen)+ypost)=27; // Even brighter.
         star[star_ref][Old_Pos]=ypost;
      }
   }

   for (star_ref=90;star_ref<101;++star_ref) // First level, 10 stars.
   {
      *((vgaScreen)+star[star_ref][Old_Pos])=0;
      ypost=star[star_ref][YPos];
      ypost=ypost+ypost;
      ypost=*(YPosChart+ypost);

      star[star_ref][XPos]+=VLevel4; // Fastest speed.

      if (star[star_ref][XPos] > ScreenWidth)
         star[star_ref][XPos]-=ScreenWidth;

      ypost+=star[star_ref][XPos];
      
      if (!CheckCoord(ypost)) // Check coordinate.
      {
         *((vgaScreen)+ypost)=30; // Brightest color.
         star[star_ref][Old_Pos]=ypost;
      }
   }
}

void SetVideoMode(byte mode)
{
   union REGS inregs,outregs;
   inregs.h.ah=0;
   inregs.h.al=mode;
   int86(0x10,&inregs,&outregs);
}

void WaitRetrace()
{
   while (!(inp(0x3da) & 8));
   while ((inp(0x3da) & 8));
}

/*
* Entry point.
*/
void main(unsigned int argc, char* argv[])
{
   char* fname=g_szFilename; // Default filename.
   if (argc >= 2) // If we have enought arguments.
      fname=argv[1];

   FILE* stream=fopen(fname,"rb");
   if (!stream) {
      printf("%s cant open file.\n",fname);
      system("pause>nul"); // Press Any key...
      exit(1);
   }
   if ('B'!=fgetc(stream) || 'M'!=fgetc(stream)) {
      fclose(stream);
      printf("%s is not a bitmap file.\n",fname);
      system("pause>nul");
      exit(1);
   }
   int nWidth,nHeight; // Check picture format.
   fseek(stream,18,SEEK_SET);
   fread(&nWidth,sizeof(int),1,stream);
   fseek(stream,22,SEEK_SET);
   fread(&nHeight,sizeof(int),1,stream);
   if (nWidth>320 || nHeight>200) {
      fclose(stream);
      printf("%s is picture format not supported.\n",fname);
      system("pause>nul");
      exit(1);
   }
   int nColors; // Check dept colors.
   fseek(stream,28,SEEK_SET);
   fread(&nColors,sizeof(int),1,stream);
   if (nColors>8) {
      fclose(stream);
      printf("%s is bitmap dept colors need 256 (8BPP).\n",fname);
      system("pause>nul");
      exit(1);
   }
   g_nSize=nWidth*nHeight;

   // Allocate buffer memory.
   byte* scrImage=(byte*)malloc(g_nSize);
   if (!scrImage) {
      fclose(stream);
      printf("Error allocating memory.");
      system("pause>nul");
      exit(1);
   }   
   fseek(stream,1078,SEEK_SET);// Set pointer to data and load.

   for (long i=(nHeight-1)*nWidth;i>=0;i-=nWidth) {
      for (long x=0;x<nWidth;++x) {
         byte a=fgetc(stream);
         scrImage[i+x]=a;
      }
   }
   fclose(stream);

   pTable=(unsigned int*)malloc(g_nSize*2);
   if (!pTable) {
      printf("Error allocating screen memory #2.\n");
      system("pause>nul");
      exit(1);
   }

   YPosChart=(unsigned int*)malloc(ScreenHeight);
   if (!YPosChart) {
      printf("Error allocating screen memory #3.\n");
      system("pause>nul");
      exit(1);
   }

   SetVideoMode(0x13); // Set video mode to graphics mode 320X200X256

   // Display the bitmap.
   int nCount=0;
   unsigned int nOffset=0;
   int x = 50; int y = 50;   
   for (int n=0;n<g_nSize;++n)
   {
      // The memory location to write to for
      // pixel (x,y) is A000h + (y * 320) + x
      vgaScreen[(y * 320) + nOffset + x]=scrImage[n];
      pTable[n]=(y * 320) + nOffset + x;
      ++nCount;
      ++nOffset;
      if (nCount == nWidth)
      {
         nOffset += (320 - nWidth);
         nCount = 0;
      }
   }
   // This way we can access our y-offset much quicker than calculating
   // it, and we can just add our x-position to that, and draw the dot.
   for (unsigned int d=0;d<ScreenHeight;++d)
      *(YPosChart+(d*2))=d*ScreenWidth;

   while (!kbhit())
   {
      display_stars();
      WaitRetrace();
   }
   free(scrImage); // Clean up.
   free(YPosChart);
   free(pTable);
   SetVideoMode(0x03); // Return to text mode.
}
Вложения
ODLogo.zip
(28.15 Кб) Скачиваний: 240
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 478
Зарегистрирован: 04 сен 2025, 19:35

След.

Вернуться в Программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9