Advertisement
Edgar_Fuentes

ASM_Problema

Sep 10th, 2016
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define WIN32_LEAN_AND_MEAN //No agrega librerías que no se vayan a utilizar
  2.  
  3. #include <Windows.h>
  4. #include <stdio.h>
  5. #include <dinput.h>
  6. #include <gdiplus.h>
  7. #include <gl/gl.h>
  8. #include <gl/glu.h>
  9.  
  10. using namespace Gdiplus;
  11.  
  12. //Variables constantes
  13. /* Variable constante para calcular el ancho de la ventana */
  14. const int ANCHO_VENTANA = 800;
  15.  
  16. /* Variable constante para calcular el alto de la ventana */
  17. const int ALTO_VENTANA = 600;
  18.  
  19.  
  20. /* Variable constante que define la cantidad de bytes por pixel, usada en las operaciones de desplegar sprites/imagenes en pantalla */
  21. const int BPP = 4;
  22.  
  23. /* Variable constante que define el intervalo del contador o timer en milisegundos,
  24.     con cada TICK del contador se ejecuta el codigo dentro del case WM_TIMER en la funcion WndProc */
  25. const int TICK = 100;
  26.  
  27. /* Variables constantes de los colores primarios de un pixel de 32 bits */
  28. const unsigned int BLUE = 0xFF0000FF;
  29. const unsigned int GREEN = 0xFF00FF00;
  30. const unsigned int RED = 0xFFFF0000;
  31.  
  32. /* Estructura con las coordenadas de los sprites en pantalla en un plano 2D */
  33. struct POSITION {
  34.     int X;
  35.     int Y;
  36. };
  37.  
  38. /* Estructura con las dimensiones de los sprites a cargar y desplegar en pantalla */
  39. struct DIMENSION {
  40.     int ANCHO;
  41.     int ALTO;
  42. };
  43.  
  44. /* Estructura con la enumeracion de algunas teclas.
  45.     Se tiene un objeto o variable del tipo de esta estructura, llamado 'input'
  46.     que sera para acceder a cada uno de las elementos de la enumeracion; ejemplo:
  47.     input.A para la tecla 'A'.*/
  48. struct Input
  49. {
  50.     enum Keys
  51.     {
  52.         Backspace = 0x08, Tab,
  53.         Clear = 0x0C, Enter,
  54.         Shift = 0x10, Control, Alt,
  55.         Escape = 0x1B,
  56.         Space = 0x20, PageUp, PageDown, End, Home, Left, Up, Right, Down,
  57.         Zero = 0x30, One, Two, Three, Four, Five, Six, Seven, Eight, Nine,
  58.         A = 0x41, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
  59.         NumPad0 = 0x60, NumPad1, NumPad2, NumPad3, NumPad4, NumPad5, NumPad6, NumPad7, NumPad8, NumPad9,
  60.         F1 = 0x70, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12
  61.     };
  62. }input /* declaracion del objeto de la estructura Input */;
  63.  
  64. //Variables Globales
  65. int *ptrBuffer;
  66. unsigned char * ptrBack;
  67. DIMENSION dmnBack;
  68. bool KEYS[256];
  69.  
  70. DIMENSION dmnMonito;
  71. unsigned char *ptrMonito;
  72.  
  73.  
  74. //Declaracion de funciones
  75. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  76. void MainRender(HWND hWnd);
  77. void Init();
  78. void KeysEvents();
  79. unsigned char * CargaImagen(WCHAR rutaImagen[], DIMENSION * dmn);
  80. POSITION setPosition(int x, int y);
  81. void DibujaFondo(int *buffer, int *imagen, DIMENSION dmn);
  82. void Monito(int * buffer, int * imagen, DIMENSION dmn);
  83. int WINAPI wWinMain(HINSTANCE hInstance,
  84.                      HINSTANCE hPrevInstance,
  85.                      PWSTR pCmdLine,
  86.                      int nCmdShow)
  87. {
  88.     WNDCLASSEX wc;                                  // Windows Class Structure
  89.     HWND hWnd;
  90.     MSG msg;
  91.  
  92.     TCHAR szAppName[] = TEXT("MyWinAPIApp");       
  93.     TCHAR szAppTitle[] = TEXT("LENS App");
  94.  
  95.     hInstance = GetModuleHandle(NULL);              // Grab An Instance For Our Window
  96.  
  97.     wc.cbSize           = sizeof(WNDCLASSEX);
  98.     wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   // Redraw On Size, And Own DC For Window.
  99.     wc.lpfnWndProc      = (WNDPROC) WndProc;                    // WndProc Handles Messages
  100.     wc.cbClsExtra       = 0;                                    // No Extra Window Data
  101.     wc.cbWndExtra       = 0;                                    // No Extra Window Data
  102.     wc.hInstance        = hInstance;                            // Set The Instance
  103.     wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);          // Load The Default Icon
  104.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);          // Load The Arrow Pointer
  105.     wc.hbrBackground    = (HBRUSH) (COLOR_WINDOW + 1);          // No Background Required For GL
  106.     wc.lpszMenuName     = NULL;                                 // We Don't Want A Menu
  107.     wc.lpszClassName    = szAppName;                            // Set The Class Name
  108.     wc.hIconSm          = LoadIcon(NULL, IDI_APPLICATION);
  109.    
  110.     if (!RegisterClassEx(&wc))                                  // Attempt To Register The Window Class
  111.     {
  112.         MessageBox(NULL,
  113.             L"Fallo al registrar clase (Failed To Register The Window Class).",
  114.             L"ERROR",
  115.             MB_OK|MB_ICONEXCLAMATION);
  116.         return 0;
  117.     }
  118.  
  119.     hWnd = CreateWindowEx( 
  120.         WS_EX_CLIENTEDGE | WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,  // Extended Style For The Window
  121.         szAppName,                          // Class Name
  122.         szAppTitle,                         // Window Title
  123.         WS_OVERLAPPEDWINDOW |               // Defined Window Style
  124.         WS_CLIPSIBLINGS |                   // Required Window Style
  125.         WS_CLIPCHILDREN,                    // Required Window Style
  126.         0, 0,                               // Window Position
  127.         ANCHO_VENTANA,                      // Calculate Window Width
  128.         ALTO_VENTANA,                       // Calculate Window Height
  129.         NULL,                               // No Parent Window
  130.         NULL,                               // No Menu
  131.         hInstance,                          // Instance
  132.         NULL);                              // Pass this class To WM_CREATE                            
  133.  
  134.     if(hWnd == NULL) {
  135.         MessageBox(NULL,
  136.             L"Error al crear ventana (Window Creation Error).",
  137.             L"ERROR",
  138.             MB_OK|MB_ICONEXCLAMATION);
  139.         return 0;
  140.     }
  141.        
  142.     SetForegroundWindow(hWnd);                      // Slightly Higher Priority
  143.     Init();
  144.     ShowWindow(hWnd, nCmdShow);
  145.     SetFocus(hWnd);
  146.  
  147.     SetTimer(hWnd, TICK, TICK, NULL);
  148.     ZeroMemory(&msg, sizeof(MSG));
  149.  
  150.     while(GetMessage(&msg, NULL, 0, 0)) {
  151.         TranslateMessage(&msg);
  152.         DispatchMessage(&msg);
  153.     }
  154.    
  155.     return(int)msg.wParam;
  156. }
  157.  
  158. /* Funcion tipo Callback para el manejo de los eventos de la ventana.
  159.     */
  160. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  161. {
  162.     switch(uMsg)                                    // Check For Windows Messages
  163.     {
  164.         case WM_TIMER:
  165.             if(wParam == TICK)
  166.             {
  167.                 MainRender(hWnd);
  168.             }
  169.             break;
  170.         case WM_PAINT:
  171.             {
  172.                 HDC hdc;
  173.                 PAINTSTRUCT ps;
  174.                 hdc = BeginPaint(hWnd, &ps);
  175.  
  176.                 BITMAP bm;
  177.                 HBITMAP h_CMC = CreateBitmap(ANCHO_VENTANA, ALTO_VENTANA, 1, 32, ptrBuffer);
  178.                 HDC hdcMem = CreateCompatibleDC(hdc);
  179.                 HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, h_CMC);
  180.                 GetObject(h_CMC, sizeof(bm), &bm);
  181.  
  182.                 BitBlt(hdc, 0, 0, ANCHO_VENTANA, ALTO_VENTANA, hdcMem, 0, 0, SRCCOPY);
  183.  
  184.                 DeleteObject(h_CMC);
  185.                 SelectObject(hdcMem, hbmOld);
  186.                 DeleteDC(hdcMem);
  187.                 DeleteObject(hbmOld);
  188.             }
  189.             break;     
  190.         case WM_KEYDOWN:                           
  191.             {
  192.                 KEYS[ wParam ] = true;
  193.             }
  194.             break;
  195.         case WM_KEYUP:
  196.             {
  197.                 KEYS[ wParam ] = false;
  198.             }
  199.             break;
  200.         case WM_CLOSE:
  201.             {
  202.                 DestroyWindow(hWnd);
  203.             }
  204.             break;
  205.         case WM_DESTROY: //Send A Quit Message
  206.             {
  207.                 KillTimer(hWnd, TICK);
  208.                 PostQuitMessage(0);
  209.             }
  210.             break;
  211.         default:
  212.             return DefWindowProc(hWnd, uMsg, wParam, lParam);
  213.     }
  214.  
  215.     return 0;
  216. }
  217.  
  218. /* Funcion usada para la inicializacion de variables y reserva de espacio en memoria.
  219.     */
  220. void Init()
  221. {
  222.     for(int i = 0; i < 256; i++)
  223.     {
  224.         KEYS[i] = false;
  225.     }
  226.  
  227.     //Inicializar el puntero tipo int 'ptrBuffer' que contiene la direccion inicial  del area de memoria reservada para el despliegue de sprites/imagenes.
  228.     ptrBuffer = new int[ANCHO_VENTANA * ALTO_VENTANA];
  229.     //Inicializar el puntero tipo unsigned char 'ptrBack' que contiene la direccion inicial en memoria del arreglo de pixeles de la imagen especificada en el primer parametro
  230.     //y en la variable dmnBack de tipo DIMENSION* estan los valores de ANCHO y ALTO de la imagen.
  231.     ptrBack = CargaImagen(TEXT("color.png"), &dmnBack); //puntero a la imagen
  232.     ptrMonito = CargaImagen(TEXT("medusa.png"), &dmnMonito);
  233. }
  234.  
  235. /* Funcion principal. Encargada de hacer el redibujado en pantalla cada intervalo (o "tick") del timer que se haya creado.
  236.     @param hWnd. Manejador de la ventana.
  237.     */
  238. void MainRender(HWND hWnd)
  239. {
  240.     KeysEvents();
  241.  
  242.     DibujaFondo(ptrBuffer, (int*)ptrBack, dmnBack);
  243.     Monito(ptrBuffer, (int*)ptrMonito,dmnMonito);
  244.     //Funciones que deberan estar el final de la funcion de Render.
  245.     InvalidateRect(hWnd, NULL, FALSE);
  246.     UpdateWindow(hWnd);
  247. }
  248.  
  249. /* Funcion que regresa la posicion del sprite en pantalla.
  250.     @param x. Coordenada X en la ventana.
  251.     @param y. Coordenada Y en la ventana.
  252.     */
  253. POSITION setPosition(int x, int y) {
  254.     POSITION p;
  255.     p.X = x;
  256.     p.Y = y;
  257.     return p;
  258. }
  259.  
  260. /* Funcion para manejar eventos del teclado dependiendo de la(s) tecla(s) que se haya(n) presionado.
  261.     */
  262. void KeysEvents()
  263. {
  264.     if (KEYS[input.W] || KEYS[input.Up]) {  }
  265.     if(KEYS[input.D] || KEYS[input.Right]) { }
  266.     if(KEYS[input.S] || KEYS[input.Down]) { }
  267.     if(KEYS[input.A] || KEYS[input.Left]) { }
  268. }
  269.  
  270. /* Funcion para cargar imagenes y obtener un puntero al area de memoria reservada para la misma.
  271.     @param rutaImagen.          Nombre o ruta de la imagen a cargar en memoria.
  272.     @return unsigned char *.    Direccion base de la imagen.
  273.     */
  274. unsigned char * CargaImagen(WCHAR rutaImagen[], DIMENSION * dmn)
  275. {
  276.     unsigned char * ptrImagen;
  277.     GdiplusStartupInput gdiplusStartupInput;
  278.     ULONG_PTR  gdiplusToken;
  279.     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
  280.  
  281.     Bitmap *bitmap=new Bitmap(rutaImagen);
  282.     BitmapData *bitmapData=new BitmapData;
  283.  
  284.     dmn->ANCHO = bitmap->GetWidth();
  285.     dmn->ALTO = bitmap->GetHeight();
  286.  
  287.     Rect rect(0, 0, dmn->ANCHO, dmn->ALTO);
  288.  
  289.     //Reservamos espacio en memoria para la imagen
  290.     bitmap->LockBits(&rect, ImageLockModeRead, PixelFormat32bppRGB, bitmapData);
  291.  
  292.     //"pixels" es el puntero al area de memoria que ocupa la imagen
  293.     unsigned char* pixels = (unsigned char*)bitmapData->Scan0;
  294.  
  295.     //"tamaño" lo usaremos para reservar los bytes que necesita la imagen.
  296.     //Para calcular la cantidad de bytes total necesitamos multiplicamos el area de la imagen * 4.
  297.     //Se multiplica por 4 debido a que cada pixel ocupa 4 bytes de memoria. Noten el 3er parametro de la funcion LockBits, dos lineas de codigo arriba.
  298.     //PixelFormat32bppARGB -> Specifies that the format is 32 bits per pixel; 8 bits each are used for the alpha, red, green, and blue components.
  299.     //Mas info: https://msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat(v=vs.110).aspx
  300.     int tamaño;
  301.     tamaño = dmn->ANCHO * dmn->ALTO * 4;
  302.     //hagamos un try de la reserva de memoria
  303.     try
  304.     {
  305.         ptrImagen = new unsigned char [tamaño];
  306.     }
  307.     catch(...)
  308.     {
  309.         return NULL;
  310.     }
  311.  
  312.     //Después de este for, ptrImagen contiene la direccion en memoria de la imagen.
  313.     for(int i=0, j=tamaño; i < j; i++)
  314.     {
  315.         ptrImagen[i]=pixels[i];
  316.     }
  317.  
  318.     //Es necesario liberar el espacio en memoria, de lo contrario marcaria una excepcion de no hay espacio de memoria suficiente.
  319.     bitmap->UnlockBits(bitmapData);
  320.     delete bitmapData;
  321.     delete bitmap;
  322.      
  323.     GdiplusShutdown(gdiplusToken);
  324.  
  325.     return ptrImagen;
  326. }
  327.  
  328. #pragma region LENS_CODE
  329. void DibujaFondo(int * buffer, int * imagen, DIMENSION dmn) {
  330.     __asm {
  331.         ;Inicializar registros indices
  332.         ;con la direccion inicial en memoria de la imagen a desplegar (fuente -> imagen -> registro indice fuente -> ESI)
  333.         ;y del area de memoria reservada para el despliegue (destino -> buffer -> registro indice destino -> EDI)
  334.         mov esi, imagen
  335.         mov edi, buffer
  336.  
  337.         ;Cargar la direccion en memoria de la variable 'dmn' el registro base (EBX). 'dmn' es la estructura con el ANCHO y ALTO.
  338.         lea ebx, dmn
  339.  
  340.         ;Transferir o copiar 4 bytes en memoria a partir de la direccion en memoria especificada por EBX;
  341.         ;son 4 bytes porque el operando destino es de 4 bytes en este caso es el registro acumulador (EAX).
  342.         ;Es decir, EBX es un puntero a 'dmn' donde 'dmn' es de 8 bytes (4Bytes de la variable ANCHO y los siguientes 4Bytes de la variable ALTO),
  343.         ;entonces EAX = ANCHO
  344.         mov eax, [ebx]
  345.  
  346.         ;sumar 4 al registro puntero (EBX) para apuntar al siguiente elemento de la estructura DIMENSION el cual es ALTO y vendria siendo el otro factor de la multiplicacion
  347.         add ebx, 4
  348.  
  349.         ;Especificar el otro factor en la instruccion de multiplicacion que son los siguientes 4Bytes a partir de la direccion especificada por EBX (variable ALTO de DIMENSION)
  350.         ;Se multplican ANCHO (=EAX) * ALTO (=dword ptr [ebx])
  351.         ;con 'dword ptr [ebx]' estamos indicando que EBX se comporte como puntero tipo DWORD,
  352.         ;es decir, se esta especificando que se desean los 4Bytes (4Bytes=1Dword) a partir de la direccion en memoria especificada por el registro EBX
  353.         ;el cual contiene la direccion inicial de la variable ALTO en la estructura DIMENSION.
  354.         mul dword ptr [ebx]
  355.         mul BPP
  356.  
  357.         ;el resultado de la multiplicacion anterior es del doble del tamano de los factores, en este caso los factores son de 4Bytes por lo que el resultado es de 8Bytes
  358.         ;y se encuentra en EDX:EAX donde EDX contiene los 4Bytes de mayor peso del producto de la multiplicacion y EAX contiene los 4Bytes de menor peso.
  359.         ;Como el producto de la multiplicacion sabemos y esperamos que es un valor con un tamano menor a 4Bytes entonces dicho resultado esta en EAX
  360.         ;y con la siguiente instruccion se lo copiamos al registro contador (ECX)
  361.         ;para posteriormente hacer el ciclo/bucle de leer cada pixel de la imagen en memoria y pasarlo al buffer (area de mem. reservada para el despliegue)
  362.         mov ecx, eax
  363.  
  364.         ;poner codigo para el bucle de leer pixel por pixel y transferirlo al buffer.
  365.            
  366.         rep movs
  367.                
  368.            
  369.     }
  370. }
  371.  
  372. void Monito(int * buffer, int * imagen, DIMENSION dmn) {
  373.  
  374.     __asm {    
  375.  
  376.         mov esi, imagen
  377.         mov edi, buffer    
  378.  
  379.  
  380.         lea ebx, dmn
  381.         mov eax, [ebx];EAX = ANCHO
  382.         add ebx, 4;EBX = ALTO
  383.         mul dword ptr[ebx]
  384.         mul BPP    
  385.         mov ecx,eax
  386.         rep movsb
  387.  
  388.    
  389.  
  390.    
  391.     }
  392. }
  393. #pragma endregion
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement