Etiquetas

C (31) Cpp (28) Linux (14) asm (8) Telegram (5) bot (5) libreria (5) Algoritmo (3) Errores comunes (3) python (3) Opengl (2) kali (2) Android (1) Snippet (1) nano (1) recursividad (1)

sábado, 16 de diciembre de 2023

Simulador Sistema Operativo

 /***********************************************

 Nombre: Simulador Descripción: Primera parte de la creación de un simulador                          de sistema operativo RR. Fecha:13-01-09 Autor:Bruno Kröller da Silva ************************************************/  

// Cabecera de librerías 

#include <stdio.h>              // Uso de printf,... 

#include <stdlib.h>             //Uso de atoi,... 

#include <unistd.h>             //Uso de waitpid,... 

#include <sys/types.h>  // Uso de rand,... 

#include <string.h>             // Uso de  //VARIABLES GLOBALES #define N_MAX 15

 #define T_MAX 30 

#define T_MIN 5 

 //FUNCIONES int hijos(int n_maximo,int quantum,int tiempo); 

 // Función main que recive parametros de entrada int main (int argc, char *argv[]){

  // Variables de entorno. int resultado; // 0 error 1 correcto int tiempo;int n_maximo;int quantum;  //Valores predefinidos de las variables. n_maximo=5;quantum=80;resultado=0;  /* Controlamos que el número de argumentos sea correcto, en caso contrario no empezamos a ejecutar las funciones principales.*/ if(argc==1 || argc==3 || argc==5 || argc>6){ printf("\t\n Error, el formato es n p m q t");} else{ /*Si entran dos argumentos, nombre + tiempo*/ if(argc==2){ tiempo=atoi(argv[2]); if(1<=tiempo<=120){resultado=1;}}  /*Si entran 4 argumentos, nombre+ numero+ p + tiempo o nombre+ quantum+ q + tiempo*/ else if(argc==4){ tiempo=atoi(argv[4]); if(*argv[2]=='p' && 1<=tiempo<=120) { n_maximo=atoi(argv[1]); resultado=1; } if(*argv[2]=='q' && 1<=tiempo<=120){ quantum=atoi(argv[1]); resultado=1; }}  /*Si entran argumentos, nombre+ numero+ p+ quantum+ q + tiempo*/ else if(argc==6){ tiempo=atoi(argv[6]); if(*argv[2]=='p' && *argv[4]=='q' && 1<=tiempo<=120){ n_maximo=atoi(argv[1]); quantum=atoi(argv[3]); resultado=1;}}  // SAlIDA DEl PROGRAMA if(resultado==1){ printf("\t\n Simulador: "); printf("\t\n       Numero maximo de programas: %d ",n_maximo); printf("\t\n       Quantum : %d",quantum); printf("\t\n       Tiempo de ejecución: %d ",tiempo); } else{ printf("\t\n Error al introducir los parametros:"); printf("\t\n [numero_prog] [p] [quantum] [q] [tiempo] ");} } return 0;}  int hijos(int n_maximo,int quantum,int tiempo){ int error; // 1 correcto, 0 error. pid_t pid_h; // Variable donde almacenaremos el pid del hijo int numero;int i;int tiempo_max;  //INICIALIZACIÓN DE VALORES i=0;error=1;  /*LANZAMIENTO DEL SISTEMA OPERATIVO*/ //Creamos un hijo pid_t fork(); //Pedimos que nos diga su pid pid_h=getpid(); //Comprobamos que el hijo se ha creado if(pid_h==-1){error=0;} else{ //Ejecutado por el padre if(pid_h!=0){waitpid(pid_h,NULL,0);} //Ejecutado por el hijo else{ //Ejecutar el S.O. //Aquí termina el hijo exit(0);}         }  /*LANZAMIENTO DE LA TEMPORIZACIÓN.*/ //Creamos un hijo pid_t fork(); //Pedimos que nos diga su pid pid_h=getpid(); //Comprobamos que el hijo se ha creado if(pid_h==-1){error=0;} else{ //Ejecutado por el padre if(pid_h!=0){waitpid(pid_h,NULL,0);} //Ejecutado por el hijo else{ sleep(tiempo); printf("\t\n Temporizador: "\ "Finalizado el tiempo de simulación "); //Aquí termina el hijo exit(0);}         }  /*LANZAMIENTO DE LA TEMPORIZACIÓN.*/ //CREARCIÓN DE LOS 10 HIJOS while(i<10){ srand(time(0)); //Generamos un numero no mayor que N_MAX //Le sumamos 1 para que empiece en 1. numero=1+rand()%(N_MAX); //Generamos el tiempo de espera de cada hijo. //Crea números en un intervalo de 5 a 30. tiempo_max=5+rand()%21; //Tiempo de espera para crear el siguiente hijo. sleep(numero); //CREAR HIJO pid_t fork(); } pid_h=getpid(); if(pid_h==0){ sleep(tiempo_max); printf("\n\t Simulador: "\ "Lanzando programa- Tiempo ejecución %d ",tiempo_max); exit(0);} //El padre espera a que todos los hijos mueran. wait(); return(error);}  /*CHULETA DE VARIABLES Valores mínimos y máximos de:                                   mínimo  máximo Tiempo          :               1               120 Quantum         :               20              200 Programas       :               1                5  numero esta entre [1,30]*/

domingo, 10 de diciembre de 2023

Primeros pasos en Opengl

/*Este tutorial cubre los primeros conceptos previos a la
creación de aplicaciones con OpenGL y en general a la
creación de contenido 3d. Es necesario aclarar que el
tutorial, por simplicidad y extensión se enfoca sobre la
especificación 1.1 de OpenGL, es decir, solo se menciona la
funcionalidad de la llamada “Fixed Pipeline” (ahora con la
entrada de OpenGL 2.0 y la introducción de los shader al
estándar, la estructura cambio).

En el tutorial se mencionan algunas palabras en ingles,
acompañadas de su traducción al español, solo para conservar
el término original (en ingles) y facilitar la búsqueda
posterior del término, tanto en español, como en inglés.

¿Qué es OpenGL? : OpenGL (Open Graphics Library) es un API
(de Aplication Programming Interface, Interfaz de
Programación de Aplicaciones) libre, multiplataforma,
orientado a la creación de contenido 3d. A un nivel más
simple se puede decir que es una librería que permite hacer
software con gráficos 3d sin preocuparse por el hardware en
que se va a ejecutar y que tiene un gran soporte en diferentes
sistemas operativos como Windows, OS/2, UNIX, FreeBSD , Linux,
etc.
Hay que hacer una diferencia clara, OpenGL no es un lenguaje
de programación, pero se puede trabajar con él desde
diferentes lenguajes como c++, c#, java y Visual Basic.

¿Para que puedo usar OpenGL? : OpenGL puede ser usado para
todo tipo de aplicaciones que necesiten visualización 3d en
tiempo real de alto rendimiento y calidad, en esto están
incluido los videojuegos, CAD, aplicaciones científicas,
médicas, militares, simuladores, etc.

¿Qué necesito para utilizar OpenGL en mis programas? Es buena
idea utilizar un IDE como Visual Studio, Eclipse o DevCpp
para realizar los programas, ya que facilita mucho el trabajo,
adicionalmente, en los archivos fuente donde se utilicen
funciones de OpenGL es necesario incluir las bibliotecas de
prototipos gl.h y glu.h, que generalmente se encuentran
preinstaladas no solo en Visual Studio, sino en otros entornos
donde se soporta el uso de OpenGL. También es necesario hacer
un link con las librerías binarias, en Visual Studio las dos
cosas se verían como:
*/
//Inclusión de las librerías prototipo
#include <gl/gl.h>
#include <gl/glu.h>

//Link con las librerías binarias
#pragma comment(lib, “opengl32.lib”)
#pragma comment(lib, “glu32.lib”)

/*es necesario pasar a algunos conceptos fundamentales del 3d.

SISTEMAS DE COORDENADAS
Para trabajar gráficos bien sea 2d o 3d es necesario tener una
forma de describir la posición de un objeto cualquiera en el
espacio. Para esto es necesario establecer un patrón de
referencia, lo cual se hace generalmente a través de un
sistema de coordenadas y el sistema al que mas estamos
acostumbrados es el de coordenadas cartesianas, en el cual un
punto puede ser expresado como una distancia a través uno (x),
dos (x,y) o tres ejes (x,y,z) mutuamente perpendiculares que
se intersecan en el punto (0,0) en el caso de dos dimensiones
y (0,0,0) en el caso de tres.
OpenGL maneja los sistemas 2d y 3d, aunque el sistema de 2d
sobre píxeles en pantalla es bastante ineficiente, por lo que
en la mayoría de los casos mejor utilizar 3d y simular el 2d
con una proyección ortográfica de la escena.
Si bien la forma en que se representan las coordenadas
cartesianas en matemáticas es bastante estándar (‘x’ positivo
a la derecha y ‘y’ positivo arriba), en los sistemas de dibujo
en el computador hay variaciones dependiendo del sistema de
dibujo sobre el cual se esté trabajando y el caso del 3d es
totalmente dependiente de desde donde, hacia donde y que es
“arriba”. Esto quiere decir que las coordenadas del sistema
abstracto no tienen que ser concordantes con el sistema de
coordenadas sobre la pantalla, por lo que se deber realizar
un proceso llamado mapeo de coordenadas. En este caso el
mapeo debe hacerse del sistema abstracto de coordenadas de
OpenGL al sistema de coordenadas en ventana del sistema
operativo (window, UNIX, linux, mac, etc). El siguiente
esquema muestra tres posibles formas de realizar el mapeo de
coordenadas
El grafico muestra tres de las posibles formas de realizar el
mapeo las coordenadas. En el Modo 1, el punto (0,0) en
coordenadas de dibujo es el correspondiente al extremo
inferior izquierdo de la ventana y el punto (200,200) estará
en el extremo superior derecho. Tal vez es uno de los modos
que parece más “natural”

En el Modo 2, el punto (0,0) en coordenadas de dibujo es el
centro de la ventana y los puntos extremos estarán situados en
los cuatro cuadrantes, en (100,100) superior derecha,
(-100,100) superior izquierda, (-100.-100) inferior izquierda
y (100,-100) inferior derecha. Este modo es similar a la forma
en que lo muestra la cámara por defecto de OpenGL, con el
agregado del eje ‘z’ positivo “saliendo” de la pantalla.

En el Modo 3, el punto (0,0) en coordenadas de dibujo se
encuentra en el extremo superior izquierdo de la ventana y el
punto (200,200) corresponde al extremo inferior derecho. Hay
que notar, que en este modo el eje ‘y’ positivo se encuentra
“cabeza abajo”, es decir, cuando un punto aumenta su
coordenada ‘y’ va hacia abajo, no hacia arriba. Este modo es
usado generalmente por los dispositivos de hardware y es la
forma por defecto de GDI.

Estas son solo algunas formas de mapeo de coordenadas y en
cualquier caso y con un poco de matemáticas (matrices de
transformación) se puede pasar de cualquier modo de mapeo a
otro.

PROYECCION

Los monitores actuales de PC, los televisores, las pantallas
de PDA, de celulares y consolas portátiles son todos
dispositivos bidimensionales, la percepción 3d sobre estos
dispositivos se debe a un conjunto de “trucos” para engañar al
ojo humano y hacerle ver objetos “tridimensionales” sobre un
dispositivo bidimensional, el primero de estos trucos es la proyección. La proyección consiste en generar una imagen bidimensional de una escena tridimensional, algo así como sacarle una foto, o pintar un cuadro de la escena. Tal vez las dos mas conocidas y las que permite trabajar OpenGL directamente son la ortográfica y la perspectiva.

Proyección Ortográfica: En este tipo de proyección se trazan rayos paralelos al plano de proyección (son paralelos porque se considera la fuente de “luz”o centro de proyección en el infinito) y la imagen se forma con aquellos rayos que intersequen al objeto. Esto se ve mas claro en el diagrama

 

Proyección en Perspectiva: La fuente de rayos en este caso no se encuentra en el infinito, sino que es un punto localizado llamado punto de fuga. Los rayos que parten del punto de fuga e intersecan al objeto son entonces los que formaran la imagen sobre el plano de proyección  En la proyección en perspectiva los objetos sufren una deformación por la distancia, a medida que los objetos se alejan del plano de proyección “disminuyen” su tamaño justo de la forma en que ocurre cuando un objetos se aleja de nuestros ojos ( en la figura se muestra como los dos objetos a pesar de ser de diferentes tamaños producen una imagen casi del mismo tamaño sobre el plano de proyección, debido a la diferencia de distancias), es por eso, que esta perspectiva es la mas utilizada para dar una sensación de realismo, como la que se necesitan en los juegos, simulaciones y animaciones.  En el caso de OpenGL, tanto en el modo de perspectiva como en el ortográfico se limita la región del espacio sobre la que se realizan los cálculos, a esta región se le llama volumen de vista o volumen de recorte (clipping volume) y en el caso de la perspectiva también se la llama frustrum por la forma que tiene. Dicha región se especifica, ya que los objetos por fuera de este campo a derecha o izquierda no aparecerán en pantalla y aquellos muy lejanos generarán pocos rasgos, por lo que de calcularse consumirían recursos innecesariamente (la consideración de “lejano” depende del programador).  En el caso de la proyección ortográfica el volumen de vista tiene forma de caja rectangular, por lo que se determina fácilmente mediante 6 medidas: near, far, top, bottom, left, right (cerca, lejos, arriba, abajo, izquierda, derecha) y en el caso de proyección, tiene forma de pirámide truncada de base rectangular, que puede ser determinada por el field of view (campo de visión), el aspect ratio ( el alto del plano mas cercano dividido el ancho), near y far.  Hay que anotar que ambos volúmenes se calculan a partir de la posición del observador, que en el caso de OpenGL es la cámara. También hay que observar que las dimensiones del plano más cercano a la cámara pueden ser mayores o menores a las de la ventana, por lo el mapeo de las condenadas no será con relación uno a uno, adicionalmente OpenGL permite definir el viewport (vista), es decir la región sobre la ventana en la que se va a realizar el dibujado, que puede ser menor al tamaño de la ventana.  Hasta este punto el tutorial ha mostrado algunos conceptos básicos relacionados con la forma en que OpenGL trabaja los gráficos tridimensionales, conceptos que posteriormente se verán reflejados en las primeras aplicaciones que se realicen con OpenGL. Es importante tomar en cuenta que un buen manejo del álgebra lineal, los TDA como las pilas y conocimientos en un lenguaje de programación como c++ permitirán avanzar más rápidamente en el aprendizaje del API OpenGL

OpenGL en Dev++

/*Escrito el 6-agosto-2006*/
/*Este tutorial aborda la creación de una ventana en Windows
con un contexto gráfico OpenGL, pero a diferencia de los
tutoriales basados en GLUT o AUX, esta aplicación se
desarrollará a partir de las librerías de Windows, haciendo
todo “manualmente”. Surge la inquietud de ¿por qué hacer este
tutorial, si podría hacerse más fácilmente con GLUT, AUX o
cualquier otra librería?, la respuesta es porque este
tutorial permite conocer mejor la estructura de un programa de
Windows, que es útil si se necesita algo mas de control (y
problemas) sobre la aplicación.
Además, es divertido “ensuciarse” un poco las manos con el API
de Windows de bajo nivel.

PROGRAMANDO ORIENTADO A EVENTOS
Windows y en general los sistemas operativos GUI utilizan una
arquitectura orientada a eventos para manejar la interacción
usuario – sistema – aplicación de manera organizada y
eficiente. El modelo es bastante simple, cada vez que el
usuario realiza una acción, el sistema determina sobre que
aplicación se realizó y le envía un mensaje describiendo la
acción, el programa lee y procesa el mensaje, si es que este
le interesa (un clic sobre el menú por ejemplo) y realiza los
cambios pertinentes.
Un ejemplo con un clic podría ser como este*/

IMAGEN

/*En este caso la aplicación, por ejemplo un juego de
estrategia, averiguaría la posición en la que en la que se
encontraba el puntero cuando se hizo el clic y movería una
unidad a esta posición. Es importante anotar que este modelo
fue creado para ser eficiente en uso de recursos cuando
varias aplicaciones corren “simultáneamente”, un videojuego
por el contrario es una aplicación destinada a consumir
recursos por su naturaleza de aplicación en “tiempo real”, la
razón de esto es que aunque el usuario se tome una siesta, el
videojuego está realizando cálculos, reproduciendo sonidos,
dibujando la pantalla, la IA esta intentando conquistar el
mundo, etc.

LA APLICACION
Las siguientes estructuras y tipos de datos serán usados en
el desarrollo de la aplicación:

HDC: Handle to Device context. Es el identificador de un
Device Context. Un Device Context es una aplicación a través
de la cual tienen que pasar las operaciones de dibujo, para
que estas puedan ser mostradas en un dispositivo físico, en
este caso particular un monitor.

PFD: Píxel Format Descriptor. Estructura que describe las
propiedades de los píxeles en una superficie de dibujado.

HWND: Handle to Window. Es el identificador de una ventana.

WNDCLASS: Estructura que contiene los datos necesarios para
el registro de una clase ventana, como son su nombre, estilo,
función de paso de mensajes, icono, cursor, entre otros.

HGLRC: Handle to GL Render Context. Es el identificador de un
Render Context, similar al HDC, solo que este no es usado por
GDI sino por OpenGL para realizar el dibujado sobre la pantalla.

Es posible dividir esta aplicación en 4 tareas principales:

Crear la ventana win32.
Preparar la ventana y ligarla a OpenGL.
Inicializar OpenGL.
Hacer el ciclo de mensajes y dibujado.

Las macros y variables del programa son:*/

#define VENTANA_ANCHO 640
#define VENTANA_ALTO  480
HDC     hdc=NULL;
HGLRC  hglrc=NULL;
HWND  hWnd=NULL;
HINSTANCE hInstance

/*CREAR LA VENTANA WIN32
Para crear la ventana es necesario llenar el WNDCLASS,
registrarlo y finalmente crear la ventana. El WNDCLASS */
    WNDCLASS    Cwnd;
    hInstance      = GetModuleHandle(NULL);
    Cwnd.style    = CS_OWNDC;
    Cwnd.lpfnWndProc    = (WNDPROC) WndProc;
    Cwnd.cbClsExtra       = 0;
    Cwnd.cbWndExtra     = 0;
    Cwnd.hInstance        = hInstance;
    Cwnd.hIcon    = NULL;
    Cwnd.hCursor            = LoadCursor(NULL, IDC_ARROW);
    Cwnd.hbrBackground   = NULL;
    Cwnd.lpszMenuName   = NULL;
    Cwnd.lpszClassName   = "OpenGL";
    RegisterClass(&Cwnd);

hWnd=CreateWindow("OpenGL","Hola Mundo",
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,100,
100,VENTANA_ANCHO,VENTANA_ALTO,NULL,NULL,hInstance,NULL);

/*
La función GetModuleHandle() obtiene un identificador para la
aplicación actual. Los datos de la estructura WNDCLASS son
los siguientes:

WNDCLASSS{
UINT style : Estilo de la aplicación, en este caso se quiere
un DC propio (CS_OWNDC)

WNDPROC lpfnWndProc : Manejador de mensajes
int cbClsExtra : Bytes extra para la estructura
int cbWndExtra : Bytes extra para la clase

HINSTANCE hInstance : Instancia de la aplicación que crea la
ventana

HICON hIcon : Icono de la ventana, al ser NULL, windows
provee el icono por defecto.

HCURSOR hCursor : Cursor usado al pasar sobre la ventana,
LoadCursor(NULL,IDI_ARROW) es el icono por defecto

HBRUSH hbrBackground : Color del fondo de la ventana,debido a
que todo el espacio de la ventana va a estar ocupado por la
ventana, este valor se provee como NULL

LPCTSTR lpszMenuName : Nombre del recurso que identifica el
menú de la aplicación, es NULL ya que no se utiliza menú.

LPCTSTR lpszClassName : Nombre de la clase que se usara al
registrarla.}

El manejador de mensajes al que hace referencia es en este
caso uno muy simple:*/

LRESULT CALLBACK WndProc
(HWND   hWnd,UINT uMsg,WPARAM wParam,LPARAM    lParam){
switch (uMsg){
case WM_CLOSE:
{PostQuitMessage(0);return 0;}}
return DefWindowProc(hWnd,uMsg,wParam,lParam);}

/*Las entradas de esta función son:

HWND hWnd : Identificador de la ventana que recibe el mensaje
UINT uMsg : El mensaje
WPARAM wParam : Información adicional sobre el mensaje
LPARAM lParam : Información adicional sobre el mensaje

Esta función solo intercepta un mensaje, aquel que es
enviado por el sistema para indicar a la aplicación que debe
cerrarse (WM_CLOSE) y si es cualquier otro mensaje lo envía
al DefWindowProc().
RegisterClass() registra una clase ventana, con los
parámetros dados por un WNDCLASS, en este caso CWnd.
Es hora de crear una ventana a partir de la clase creada con
el RegisterClass(), para esto se utiliza la función
CreateWindow() cuyos parámetros son los siguientes:

HWND CreateWindow(
LPCTSTR lpClassName : Nombre de la clase a partir de la cual
se crea la ventana
LPCTSTR lpWindowName : Titulo de la ventana.
DWORD dwStyle : Estilo de la ventana, en este caso con
titulo y borde (WS_OVERLAPED)
int x, : Posición x de la ventana
int y : Posición y de la ventana
int nWidth : Ancho de la ventana
int nHeight : Alto de la ventana
HWND hWndParent : Identificador de la ventana “padre”, en
este caso NULL, ya que no tiene HMENU menú : Identificador
del menú de la ventana, en este caso NULL, ya que no tiene
HINSTANCE hInstance : Identificador de la aplicación
poseedora de la ventana, en NT/2000/XP este valor es ignorado
LPVOID lpParam : Cadena con el parámetro a pasar al llamar
el mensaje WM_CREATE. En este NULL, ya que no hay ningun
parámetro a pasar)

 PREPARAR LA VENTANA Y LIGARLA A OPENGL.
Ahora es necesario:*/
GLuint  PixelFormat;
static  PIXELFORMATDESCRIPTOR pfd=
{sizeof(PIXELFORMATDESCRIPTOR),1,
PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0};

    hdc=GetDC(hWnd);
    PixelFormat=ChoosePixelFormat(hdc,&pfd);
    SetPixelFormat(hdc,PixelFormat,&pfd);
    hglrc=wglCreateContext(hdc);
    wglMakeCurrent(hdc,hglrc);
/*
El PIXELFORMATDESCRIPTOR tiene los siguientes datos:

PIXELFORMATDESCRIPTOR {
WORD nSize : Tamaño de la estructura
WORD nVersion : Versión de la estructura, siempre es 1

DWORD dwFlags : Propiedades del buffer de píxeles, en este
caso dibujar sobre una ventana (PFD_DRAW_TO_WINDOW), soporte
a OpenGL (PFD_SUPPORT_OPENGL) y doble buffer (PFD_DOUBLEBUFFER)

BYTE iPixelType : La forma de describir los píxeles, en este
caso como RGBA (PFD_TYPE_RGBA)

BYTE cColorBits : Tamaño de un píxel individual en bits, en
este caso 32 que es el mas común
BYTE cRedBits : Ignorado
BYTE cRedShift : Ignorado
BYTE cGreenBits : Ignorado
BYTE cGreenShift : Ignorado
BYTE cBlueBits : Ignorado
BYTE cBlueShift : Ignorado
BYTE cAlphaBits : Ignorado
BYTE cAlphaShift : Ignorado
BYTE cAccumBits : Ignorado
BYTE cAccumRedBits : Ignorado
BYTE cAccumGreenBits : Ignorado
BYTE cAccumBlueBits : Ignorado
BYTE cAccumAlphaBits : Ignorado

BYTE cDepthBits : Bits para el buffer de profundidad, pueden
ser 16 o 32 como en este caso.

BYTE cStencilBits : Ignorado
BYTE cAuxBuffers : Ignorado
BYTE iLayerType : Ignorado
BYTE bReserved : Ignorado
DWORD dwLayerMask : Ignorado
DWORD dwVisibleMask : Ignorado
DWORD dwDamageMask : Ignorado
}

GetDC() obtiene el Device Context asociado a la ventana
identificada por hWnd.

ChoosePixelFormat() utiliza dos parámetros, el hdc sobre el
cual se buscara un formato de píxeles compatible y el pfd que
especifica el formato deseado por la aplicación. Esta función
devuelve el formato de píxeles mas cercano encontrado, con
respecto al pfd.

SetPixelFormat() utilizar tres parámetros, el hdc sobre el
cual se va a establecer el formato de píxeles, un entero, el
PixelFormat, donde esta guardado el índice a dicho formato de
píxeles y el pfd de referencia que se uso para encontrar el
formato, el ultimo valor no afecta el funcionamiento de esta
función, ya que se utiliza solamente como registro.

wglCreateContext() crea un contexto de dibujo para OpenGL, a
partir de un contexto de dibujo de GDI.

wglMakeCurrent() elige un HGLRC sobre el cual se va a dibujar
los OpenGL, esto es debido a que una aplicación puede tener
varios contextos de dibujo, pero solo puede operar un proceso
sobre un contexto a la vez.

INICIALIZAR OPENGL
La inicialización de OpenGL es en este caso bastante simple y
más bien utilitaria, es realizada por las siguientes líneas de
código:*/

glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glMatrixMode (GL_PROJECTION);
glViewport (0, 0, VENTANA_ANCHO , VENTANA_ALTO);
gluPerspective(45.0f,VENTANA_ANCHO/VENTANA_ALTO,0.1f,100.0f);
gluLookAt( 0,0,16,  0,0,0, 0,1,0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();

/*
glClearColor() establece el color de fondo
glMatrixMode() escoge una matriz para operar sobre ella.
Primero se elige la de proyección (GL_PROJECTION)

glViewport() establece el tamaño del marco de dibujo de OpenGL

gluPerspective() establece el frustrum, en este caso apertura
de 45, aspecto de 640/480, plano mas visible a 0.1 de
distancia y mas lejano a 100.

gluLookAt() posiciona la "cámara" (en realidad hace
transformaciones sobre la matriz proyección. Los parámetros
están agrupado de a 3 (x, y, z) y representan la posición de
la camara, el punto al que mira y que vector es considerado
"hacia arriba"

Finalmente se vuelve al modo de matriz GL_MODELVIEW que es
el utilizado para dibujar las primitivas.

HACER EL CICLO DE MENSAJES Y DIBUJADO
El ciclo de mensajes se encarga de revisar constantemente los
mensajes, en busca de alguno de interés para la aplicación,
de no haber mensajes, se dibuja la escena de OpenGL. El
código es así
*/

MSG mensaje;
BOOL continuar=TRUE;
while(continuar){

if (PeekMessage(&mensaje,NULL,0,0,PM_REMOVE)){
if (mensaje.message==WM_QUIT){continuar=FALSE;}
else{
TranslateMessage(&mensaje);
DispatchMessage(&mensaje);
}}
else{
render();
SwapBuffers(hdc);
}}

/*
La variable continuar indica cuando el ciclo debe detenerse,
cuando el usuario o el sistema decidan cerrar la aplicación,
bien sea con la X sobre la barra de la ventana, con el método
abreviado, mediante el administrador de aplicaciones, etc.
En algunos ejemplos se obvia esta variable al hacer un ciclo
while(1) y utilizando un break; en caso de recibir el mensaje.

PeekMessage() busca y almacena un mensaje de la pila de
mensajes de la aplicación. Si tal mensaje existe lo almacena
en el primer parámetro y devuelve TRUE, de lo contrario
devuelve FALSE. El ultimo parámetro (PM_REMOVE) le indica a la
función al leer un mensaje debe borrarlo de la pila de mensajes.

En este caso solo estamos observando el mensaje WM_QUIT, que
indica que el WndProc llamo la función PostQuitMessage(), es
decir que intercepto algún mensaje de salida de la aplicación.

Si no es este mensaje, se vuelve a colocar en la pila de
mensajes mediante las funciones TranslateMessage() y
DispatchMessage, para que este pueda ser leído por el
wndProc() creado anteriormente o por el manejador de mensajes
por defecto (DefWindowProc()).

Finalmente si no hay ningún mensaje por leer en la pila de
mensajes, se hace el dibujado(render()) y se cambia de buffer
(SwapBuffers()). El código del render() es bastante simple y
pinta un triangulo
*/

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(3.0f,-2.0f,0.0f);
glVertex3f(0.0f,1.0f,0.0f);
glVertex3f(-3.0f,-2.0f,0.0f);
glEnd();

/*
glClear() limpia los buffers pasados como parámetro de acuerdo
al color de limpiado (negro) y entre las funciones glBegin() y
glEnd() esta la especificación de un triangulo de color azul

El codigo entero*/
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#define VENTANA_ANCHO 640
#define VENTANA_ALTO  480

HDC   hdc=NULL;
HGLRC      hglrc=NULL;
HWND        hWnd=NULL;
HINSTANCE   hInstance;

void inicializarGL(void){
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glMatrixMode (GL_PROJECTION);
glViewport (0, 0, VENTANA_ANCHO , VENTANA_ALTO);
gluPerspective(45.0f,VENTANA_ANCHO/VENTANA_ALTO,0.1f,100.0f);
gluLookAt( 0,0,16,  0,0,0, 0,1,0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
    }

void render(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(3.0f,-2.0f,0.0f);
glVertex3f(0.0f,1.0f,0.0f);
glVertex3f(-3.0f,-2.0f,0.0f);
glEnd();
    }

void deInicializar(void){
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hglrc);
ReleaseDC(hWnd,hdc);
DestroyWindow(hWnd);
UnregisterClass("OpenGL",hInstance);
    }

LRESULT CALLBACK WndProc
(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch (uMsg){
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}}
return DefWindowProc(hWnd,uMsg,wParam,lParam);}

int WINAPI WinMain
(HINSTANCE hinst,HINSTANCE hinstAnterior,
LPSTR cadenaDeComandos,int parametroVentana){
        MSG  mensaje;
        BOOL    continuar=TRUE;
        GLuint  PixelFormat;
        WNDCLASS    Cwnd;

        hInstance         = GetModuleHandle(NULL);
   Cwnd.style      = CS_OWNDC;
   Cwnd.lpfnWndProc    = (WNDPROC) WndProc;
   Cwnd.cbClsExtra  = 0;
   Cwnd.cbWndExtra  = 0;
   Cwnd.hInstance    = hInstance;
   Cwnd.hIcon      = NULL;
   Cwnd.hCursor        = LoadCursor(NULL, IDC_ARROW);
   Cwnd.hbrBackground  = NULL;
   Cwnd.lpszMenuName   = NULL;
   Cwnd.lpszClassName  = "OpenGL";
   RegisterClass(&Cwnd);

hWnd=CreateWindow("OpenGL","Hola Mundo",WS_OVERLAPPEDWINDOW
,100,100,VENTANA_ANCHO,VENTANA_ALTO,NULL,NULL,hInstance,NULL);

static  PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR),1,
PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0};

hdc=GetDC(hWnd);
PixelFormat=ChoosePixelFormat(hdc,&pfd);
SetPixelFormat(hdc,PixelFormat,&pfd);
hglrc=wglCreateContext(hdc);
wglMakeCurrent(hdc,hglrc);
ShowWindow(hWnd,SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
inicializarGL();

while(continuar){

if (PeekMessage(&mensaje,NULL,0,0,PM_REMOVE)){
if (mensaje.message==WM_QUIT){continuar=FALSE;}
else{
TranslateMessage(&mensaje);
DispatchMessage(&mensaje);
}}

else{
render();
SwapBuffers(hdc);
}}

deInicializar();
return (mensaje.wParam);}

/*Por ultimo:
La aplicación luce así:

Captura

Aun este programa tiene que abarcar bastantes prestaciones no
contempladas, por dar simpleza (de ser posible eso) al
Hola Mundo. Entre estas prestaciones están:

Solicitar modo pantalla completa, que es muy común entre los
videojuegos.

Atender a los errores en todo el proceso de creación de la
ventana y asociación a OpenGL. Muchas de las funciones
utilizadas en la aplicación tienen un retorno que indica si
la función pudo llevarse a cabo o no.

Cambiar de tamaño la escena de OpenGL al cambiar el tamaño de
la ventana. Esto se hace añadiendo los estilos CS_VREDRAW y
CS_HREDRAW al WNDCLASS e interceptando el mensaje
WM_SYSCOMMAND, Wparam SC_SIZE.

Pausar la aplicación cuando la ventana es puesta detrás de
otra o minimizada.

También es importante aclarar que este ejemplo utiliza el
driver de software de OpenGL creado por Microsoft en la
década del 90 y que actualmente dicho driver no es mantenido y
es muy ineficiente. Para utilizar el driver de OpenGL que
proporciona la tarjeta gráfica, que tiene la ventaja de ser
acelerado por hardware y mantenido constantemente
(dependiendo de la tarjeta) se pueden usar las funciones
WGL-ARB aprobadas en el año 2000 y que hacen actualmente
parte del estándar, aunque siempre que se quieran usar, se
debe comprobar su disponibilidad, ya que dependen de la
implementación del estándar.

Finalmente es necesario señalar que esta es una de las maneras
mas complicadas de hacer una aplicación con OpenGL para
Windows, ya que se trabaja el API de win32 a muy bajo nivel y
las funciones para ligar OpenGL con GDI no han sido
actualizada en muchos años, de hecho el articulo relevante mas
reciente que se puede encontrar en MSDN acerca de OpenGL data
del año 1995.*/

Mapeo de una dll

 /*Mapeo de una dll. No fue escrito por mi*/

 #include <C:\Dev-Cpp\All.h>

using namespace std;

int main(void){
const long addres = 0X3DE00;
char Mensa[]="jeje";

HANDLE Archivo = CreateFile(
"Mensa.dll",0,GENERIC_READ+GENERIC_WRITE,0,0,OPEN_EXISTING,0);

int size = GetFileSize(Archivo,0);

HANDLE MAPA =  CreateFileMapping(
Archivo,0,PAGE_READWRITE,0,size,0);

void* View = MapViewOfFile(MAPA,FILE_MAP_ALL_ACCESS,0,0,0);
char *ptr = (char*)View+addres;
memcpy(ptr,Mensa,sizeof(Mensa));
return 0;}

miércoles, 6 de diciembre de 2023

Bloquear Entrada,teclado y mouse

/*El codigo no es de mi autoría..*/

#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <cstdio>
using namespace std;
const char ventanas[3][65]=
{"Windows Live Messenger","Reproductor de Windows Media","Panel de control"};

HWND hwnd[3]={hwnd[0]=FindWindow(NULL,ventanas[0]),hwnd[1]=FindWindow(NULL,ventanas[1]),
hwnd[2]=FindWindow(NULL,ventanas[2])};

void buscar(){
if(hwnd[0]==NULL){cout<<"No se encontro la ventana: "<<ventanas[0]; getchar();}
else{EnableWindow(hwnd[0],false); cout<<"Se encontro la ventana: "<<ventanas[0]; getchar();}

if(hwnd[1]==NULL){cout<<"No se encontro la ventana: "<<ventanas[1]; getchar();}
else{EnableWindow(hwnd[1],false); cout<<"Se encontro la ventana: "<<ventanas[1]; getchar();}

if(hwnd[2]==NULL){cout<<"No se encontro la ventana: "<<ventanas[2]; getchar();}
else{EnableWindow(hwnd[2],false); cout<<"Se encontro la ventana: "<<ventanas[2]; getchar();}
}

int main(){
SetConsoleTitle("ventanas");
buscar();
getchar();
return 0;
}

Lista enlazada

/*EL codigo no fue hecho por mi!*/

 #include <bits/stdc++.h>
using namespace std;

// Creamos una estructura node que tendrá 2 atributos
struct node {
int value_;
node* next_ = nullptr;

/*****************************************************************
Tendremos 2 constructores, uno que inicializará los atributos con
los argumentos que le pasemos a una instancia de node
******************************************************************/
node() = default;
node(int value_) :value_{value_},next_{nullptr}{}

// Creamos 2 métodos
int value()const{return value_;}
node* next()const{return next_;}
};

// Creamos una estrucuta linked list que tendrá 3 atributos
class linked_list {
node* head_;
node* tail_;
size_t size_;

public:
linked_list() :head_{nullptr}, tail_{nullptr},size_{0}{}
linked_list(initializer_list<int> l) : head_{nullptr}, tail_{nullptr}, size_{0}
{for(auto v:l) push_back(v);}

  // Método para agregar un nodo al final de una linked list
void push_back(int data) {
node* tmp = new node(data);
    /*****************************************************************
    También podemos hacer esto, pero como nuestro constructor ya lo
    hace, no hay necesidad de inicializar cada atributo como lo hace
    el sig código:

    tmp->value_ = data;
    tmp->next_ = nullptr;
    ******************************************************************/

    /*****************************************************************
    Verificamos si el head es nulo, si es así, entonces quiere decir
    que aún no hay ningún nodo en la linked list, por lo que el nodo
    que agreguemos será tanto el head como el tail.
    Pero si el head no es nulo, entonces significa que ya hay nodos en
    la linked list. Por lo que, tenemos que agregar el nodo al final
    de la linked list, y hacer que el último nodo agregado sea el
    siguiente nodo de tail.
    ******************************************************************/
if(head_ == nullptr){head_ = tmp;tail_ = tmp;}
else{tail_->next_ = tmp;tail_ = tail_->next_;}
size_++;}

  // Método para agregar un nodo al inicio de una linked list
void push_front(int data){
node* tmp = new node(data);
    /*****************************************************************
    Verificamos si el head es nulo, si es así, entonces quiere decir
    que aún no hay ningún nodo en la linked list, por lo que el nodo
    que agreguemos será tanto el head como el tail.
    Pero si el head no es nulo, entonces significa que ya hay nodos en
    la linked list. Por lo que, tenemos que agregar el nodo al inicio
    de la linked list. Para ello, hacemos que el atributo next del
    nodo apunte al head, una vez hecho esto, hacemos que el head pase
    a puntar al nodo agregado.
    ******************************************************************/
if(head_ == nullptr){head_ = tmp;tail_ = tmp;}
else{tmp->next_ = head_;head_ = tmp;}
size_++;}

  // Método para agregar un nodo en la posición que se especifique en la linked list
void insert(size_t index, int data) {
    node* tmp = new node(data);
    /*****************************************************************
    Verificamos si el index es menor que 0 o si es mayor que el tamaño
    de la linked list, si es así, entonces no retornamos nada.
    Si el index es 0, significa que se hará una inserción al inicio de
    la linked list, por eso un push_front().
    Si el index es el mismo que el tamaño de la linked list, significa
    que se hará una inserción al final de la linked list, por eso un
    push_back().
    Y si no es ninguna de las condiciones previstas anteriormente,
    entonces creamos dos nodos, que actúen como el nodo previo y
    posterior, a continuación explicaré la lógica que consideré.
      1. Recorreremos la linked list hasta llegar una posición antes
      de la posición deseada, esto tiene por ebjetivo que los 2 nodos,
      tanto el previo como el posterior avancen.
      2. Al finalizar el loop el nodo previo debería ser el nodo que
      se encuentra una posición antes del nodo de la posición que se
      especificó y el nodo posterior debería ser el mismo nodo que el
      nodo previo.
      3. Sin embargo, una vez fuera del loop el nodo posterior será el
      le sigue, con esto, habremo conseguido las direcciones que
      necesitamos.
      4. Finalizamos el algoritmo con nuestro nodo tmp(creado al inicio)
      apuntando al nodo posterior y con el nodo previo apuntando al nodo
      tmp.
    ******************************************************************/
if(index < 0 || index > size_) return;
if(index == 0){push_front(data);return;}
if(index == size_){push_back(data);return;}
node* prevNode = head_;node* posNode = head_;

for(size_t i = 0; i < index-1; i++)
{prevNode = prevNode->next_;posNode = posNode->next_;}
posNode = posNode->next_;
tmp->next_ = posNode;
prevNode->next_ = tmp;
size_++;}

  // Método para borrar el primer nodo de la linked list
void pop_front() {
    /*****************************************************************
    Para este método crearemos 1 nodo, este será el head. Luego
    haremos que el head apunte al nodo siguiente del head. Hecho esto,
    ya podemos eliminar el nodo que guardaba al antiguo head.
    ******************************************************************/
if(size_ == 0) return; node* node = head_;
head_ = node->next_;delete node;
size_--;}

  // Método para borrar el último nodo de la linked list
void pop_back() {
    /*****************************************************************
    Para este método crearemos 1 nodo, este será el head. Luego
    haremos que el nodo sea el penúltimo. Con esto ya podemos eliminar
    el nodo siguiente y hacer que el tail apunte al penúltimo nodo.
    ******************************************************************/
    if(size_ == 0) return;
    if(size_ == 1) {
      pop_front();
      return;
    }

    node* node = head_;

    for(size_t i = 0; i < size_-1; ++i) {
      node = node->next_;
    }

    delete node->next_;
    tail_ = node;

    size_--;
  }

  // Método para borrar el nodo de posición especificada en el método
  void erase(size_t index) {
    /*****************************************************************
    Verificamos si el index es menor que 0 o si es mayor que el tamaño
    de la linked list, si es así, entonces no retornamos nada.
    Si el size es igual a cero, significa que no hay ningún nodo el la
    linked list, por lo que, no se hará nada.
    Sin embargo el index es 0, significa que se elminará al inicio de
    la linked list, por eso un pop_front().
    Si el index es el mismo que el tamaño de la linked list, significa
    que se eliminará el último nodo de  la linked list, por eso un
    pop_back().
    Y si no es ninguna de las condiciones previstas anteriormente,
    entonces primero creamos un nodo, que actúen como el nodo previo,
    a continuación explicaré la lógica que consideré.
      1. Recorreremos la linked list hasta llegar una posición antes
      de la posición deseada, esto tiene por ebjetivo que el nodo
      previo sea el nodo anterior al nodo que se quiere borrar.
      2. Al finalizar el loop el nodo previo debería ser el nodo que
      se encuentra una posición antes del nodo de la posición que se
      especificó.
      3. Después creamos un nuevo nodo(posNode) el cuál será el
      siguiente nodo del nodo previo.
      4. A su vez creamos otro nodo que sera el siguiente(nxtNode) del
      nodo posterior.
      5. Lo siguiente tendrá por objetivo hacer que el nodo previo
      apunte al nodo siguiente del posterior y después eliminará el nodo
      posterior creado.
    ******************************************************************/
    if(index < 0 || index > size_) return;
    if(size_ == 0) return;
    if(index == 0) {
      pop_front();
      return;
    }
    if(index == size_) {
      pop_back();
      return;
    }

    node* prevNode = head_;

    for(size_t i = 0; i < index-1; ++i) {
      prevNode = prevNode->next_;
    }
    node* posNode = prevNode->next_;
    node* nxtNode = posNode->next_;

    prevNode->next_ = nxtNode;
    delete posNode;
    
    size_--;
  }

  // Método para retornar el valor de una posición en la linked list
  node* get(size_t index) {
    if(index < 0 || index > size_) return nullptr;

    node* tmp = head_;
    for(size_t i=0; i<index; ++i) {
      tmp = tmp->next_;
    }
    return tmp;
  }

  // Método para retornar el indice del valor que le pasamos al método
  int search(int data) {
    node* tmp = head_;
    for(size_t i=0; i<size_; ++i) {
      if(tmp->value_ == data)
        return i;
      tmp = tmp->next_;
    }
    return -1;
  }

  // Método para retornar el tamaño de la linked list
  size_t size() {return size_;}
 
  // Método para retornar el puntero head de la linked list
  node* begin() {return head_;}

  // Método para retornar el puntero tail de la linked list
  node* end() {return tail_;}

  // Método para imprimir la linked list
  void print() {
    node* nod = head_;
    while(nod != nullptr) {
      cout << nod->value_ << " -> ";
      nod = nod->next_;
    }
  }
};

int main() {
  linked_list ll;

  // 43->NULL
  ll.push_front(43);

  // 76->43->NULL
  ll.push_front(76);

  // 76->43->15->NULL
  ll.push_back(15);

  // 76->43->15->44->NULL
  ll.push_back(44);

  // 76->43->15->44->100->NULL
  ll.insert(4, 100);

  // 76->43->15->48->44->100->NULL
  ll.insert(3, 48);

  // 22->76->43->15->48->44->100->NULL
  ll.insert(0, 22);
  ll.print();

  cout << '\n' << ll.size() << '\n';
  cout << endl;

  // Get value of the second index
  // It should be 43
  cout << "Get value of the second index:" << endl;
  node* get = ll.get(2);
  if(get != NULL) cout << get->value_;
  else cout << "not found";cout << endl << endl;

  // Find the position of value 15
  // It must be 3
  cout << "The position of value 15:" << endl;
  int srch = ll.search(15);
  cout << srch << endl << endl;

  // Remove first element
  cout << "Remove the first element:" << endl;
  ll.erase(0);
  // 76->43->15->48->44->100->NULL
  ll.print();
  cout << endl;

  // Remove fifth element
  cout << "Remove the fifth element:" << endl;
  ll.erase(4);
  // 76->43->15->48->100->NULL
  ll.print();
  cout << endl;

  // Remove tenth element
  cout << "Remove the tenth element:" << endl;
  ll.erase(9);
  // Nothing happen
  // 76->43->15->48->100->NULL
  ll.print();
  cout << endl;


  // Test 1
  linked_list ll2;
  for (size_t i = 0; i < 10; ++i) {
    ll2.push_back(i);
  }
  if(ll2.size() == 10) cout << "owo\n";

  linked_list list1 = {3, 24, 13, 64, 25};
  linked_list result;
  auto iter = end(list1)->value();

  for(auto it = list1.begin(); it != list1.end(); it+=2) {
    result.push_back(it->value());
  }
  result.push_back(iter);
  result.print();
  cout << "\n size: \t" << result.size() << "\n";
}

Candado para Carpetas

/*
El Código no fue escrito por mí...

*/

#include <stdio.h>
#include <stdlib.h>

void fn_creditos()
{
printf("Escrito originalmente por 3hy y Mrobles\n"\
"Remasterizado por Sadistski.");
}

int main(){
int opcion;
printf("___Locker en C por 3hy! Basado en el Locker en Batch por Mrobles___\n"\
"> Solo funciona en Windows.Reeditado por Sadistski.\n\n"\
"Elija la opción:"\
"\n1. Crear la carpeta de locker (mismo directorio actual)"\
"\n2. Lockear una carpeta"\
"\n3. Desbloquear la carpeta"\
"\n4. Borrar la carpeta del locker"\
"\n5. Creditos"\
"\n6. Salir\n");
scanf("%i", &opcion);

switch(opcion){
case 1: printf(CUR CEL"La carpeta se creará donde está el programa....\n");
system("mkdir locker-folder");break;

case 2:
system("attrib +h +s locker-folder\n\n");break;fn_creditos();

case 3:
system("attrib -h -s locker-folder\n\n");break;fn_creditos();

case 4:
system("del locker-folder");break;fn_creditos();

case 5: fn_creditos();exit(0);break;
default: printf("Shit, has puesto algo mal...\n\n");break;}
return 0;}