QB64

¿Os interesaría poder compilar vuestros antiguos fuentes escritos en IBM BASIC/BASICA, Microsoft GW-BASIC, Microsoft QBASIC, Microsoft QuickBASIC, Microsoft BASIC Compiler (PDS), o Visual Basic para DOS para Windows x86, Linux x86 o Linux x64?



En caso afirmativo, tenéis disponible QB64, un entorno de desarrollo en modo texto, similar al de QuickBASIC, con una compatibilidad casi del 100% sobre el código de éste. En mi caso, tengo multitud, por no decir cientos de pequeños programitas en BASIC para PC, y ha sido un descubrimiento totalmente revelador. Es cierto que una vez me pasé a Turbo BASIC, con su sintaxis algo diferente, se perdió la compatibilidad QB, pero para eso sigue estando Power BASIC, ¿no es cierto?

Hablando de alternativas, sabréis que además de Power BASIC, hay opciones como FreeBasic, PureBasic, etc, pero al igual que Visual Basic .NET, son dialectos derivados de BASIC, pero que implementan características más modernas de diferente índole, que los hacen incompatibles con el código antiguo.

Los ejecutables que se generan, son por tanto binarios totalmente nativos, aunque lamentablemente, requieren algunas dependencias externas como SDL para funcionar, sin duda, una pena que todavía no permitan hacer compilaciones estáticas. Pero no os desesperéis, porque QB64, está todavía en la versión 0.9, y no es un producto terminado, así que paciencia, que irán viniendo más novedades.

El entorno de desarrollo, imita al interfaz en modo texto de QBASIC y QuickBASIC, lo encuentro poco práctico, pero le da un toque retro que tiene su punto.

Sobre el caso que nos ocupa, QB64, funciona transformando el fuente BASIC a C++, que luego es compilado con G++, y enlazado con las funciones que implementan las características del lenguaje BASIC original. Está tan trabajado, que es incluso capaz de emular los sonidos de BEEP y PLAY, para que funcionen desde la tarjeta de sonido de nuestro entorno.

La velocidad de ejecución de los programas compilados, es buena. Por un lado, como digo, es código nativo, al igual que lo fuera en su día QuickBASIC o Visual BASIC for DOS, pero por otro, vamos a estar ejecutando nuestros programas diseñados para 8086, 286 o 386 de la época, en como mínimo un Pentium 4, es decir, hablamos de que en el peor de los casos, tendrán 50 veces más potencia de cálculo disponible que el original, lo que puede ser una ventaja, o bien un problema, como el caso de abajo, donde a Nibbles, hay que aumentarle los tiempos de espera si queremos que sea jugable. Por lo demás, la compilación de Nibbles.bas, no ha requerido ningún cambio en el código.



21 comentarios en “QB64”

  1. SIn querer queriendo me pongo a recordar mis tiempos de programador en QBasic aquellos tiempos horas y horas metido en el computador…

    Me dio gusto de que aun exista una comunidad de programadores en qbasic y se este actualizando cada ves mas…

  2. Manuel Sánchez Carrilero

    Yo utilizo QB64 es muy rápido. Tiene unos gráficos muy potentes con nuevas instrucciones añadidas, que permite altas resoluciones con millones de colores a voluntad del usuario.

    Los tipos de datos, con nuevas instrucciones, son apabullantes: por ejemplo los arrays de strings (cadenas), teniendo suficiente memoria, te permite implementar operaciones aritméticas con «big numbers: APA».

    Y todo con la misma filosofía de los clásicos de la antigüedad, pero con una potencia increíble.

  3. Gracias por tu comentario Manuel Sánchez Carrilero. Me gustaría que pudieras darme más información sobre la velocidad de QB64. Cuando la probé con la implementación Sieve en BASIC, se comportó extremadamente lento. De hecho, fue el más lento de todos los contendientes, y el que generó ejecutables de mayor tamaño con mucha diferencia.

    He aprovechado para hacer una prueba rápida, con el último snapshot de QB64 1.1, usando el mismo SIEVE.BAS que utilicé en su día. El ejecutable resultante ha sido de 1.460.224 bytes, y ha tardado en ejecutarse 74,385 segundos. El mismo programa en PB/CC 5, era un ejecutable de 15.872 bytes, y tardó en ejecutarse 10,757 segundos. Es decir, al menos con el cálculo de números primos en la Criba de Eratóstenes, sus binarios son 10 veces más grandes, y 7 veces más lentos. Actualizando Powerbasic Console Compiler a la 6.04, el ejecutable se ha visto reducido más aún, hasta los 14.336 bytes, y la ejecución ha sido ligeramente más rápida: 10,173 segundos. Similar a lo que ya verifiqué en Sieve en PB/CC 6.04.

    Tampoco le veo que destaque en cuanto a configuraciones de pantalla, o funciones disponibles, pero puedo estar equivocado, por ello agradezco tu opinión.

    Los Big Numbers me gusta mucho. Es muy útil, pero no he encontrado documentación al respecto, el mayor tipo de datos que veo es _UNSIGNED _INTEGER64. ¿Podrías ponerme algún enlace o ejemplo?

  4. Manuel Sánchez Carrilero

    Muy amable por tu respuesta.

    Yo utilizo QB64 únicamente como herramienta. Todo lo que pueda opinar sobre el propio software es muy subjetivo. Por eso cuando comentaba que era muy rápido, me refería a que emplea un instante en ejecutar sencillos códigos, mientras que otros Basic se atascan, pero sin nada de medidas.

    Utilizando la sentencia SCREEN _NEWIMAGE(1260, 940, 32), obtengo una resolución de 1260 x 940 sobre mi pantalla de 19” con 2^24 = 256 x 256 x 256 colores, por medio de la instrucción de color _RGB(cr, cg, cb) puesta en cualquier sentencia gráfica PSET, LINE, etc.

    Sobre “big number” nada se encuentra para QB64, mira tal vez:
    https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic
    http://www.runbasic.com/
    http://fractaljourney.blogspot.com.es/2011/04/mandelbrot-ultra-zoom-6-10e185.html

    Como es bien sabido los tipos SINGLE y DOUBLE que actúan muy rápidos, pueden representar valores reales enormes, pero solo con precisiones máximas de 7 y 16 dígitos, respectivamente.

    El tipo _UNSIGNED _INTEGER64, como bien dices, maneja valores enteros del orden de 18 trillones, pero con precisión de tan solo 20 dígitos, etc. Todos ellos son insuficientes en lo que al número de dígitos significativos se refiere, para ciertas aplicaciones como la comentada de los “big numbers”.

    Aquí, el número de caracteres (bytes) que puede, teóricamente, admitir un string es 2 Gbyte. Por otro lado el número de elementos que puede admitir un array también está en ese orden de magnitud, son pues candidatos perfectos para representar y operar con grandes números. La idea es muy sencilla: utilizar arrays de string “numéricos”, desmenuzando estos últimos en operaciones dígito a dígito como se hacía en el colegio de niños de primaria, sin necesidad de implementar librerías “ad hoc”, complicadas de manejar.

    Mis felicitaciones
    Saludos

  5. Fredi Brühl las dos primeras preguntas no tienen mucho misterio. Se descubre en pocos segundos. Por fortuna las dos preguntas se responden al mismo tiempo. Tienes un menú Run como se ve en la captura, con la opción Run que automáticamente compilará y ejecutará tu programa. Por defecto sus ejecutables son de 32 bits, así que no tendrás ningún problema ejecutándolos ni en Win32 ni en Win64.

    En cuanto al minicurso me parece una idea estupenda. Cuenta conmigo para publicarlo una vez lo tengas terminado. ¡Estamos en contacto!

  6. quisiera conseguir algun codigo fuente de qb64 utilizando el mouse en su interfaz. Creo que hay una aplicacion llamado
    Inform que permite hacer menus para utilizarlos con qb64.

  7. Vas bien encaminado humberto galvan, pero te falta profundizar un poco. Espero que esta guía te ayude a reconducir el proceso.

    Sobre códigos fuente usando el ratón, debes revisar las funciones _MOUSEINPUT y sus relacionada: (_MOUSEX, _MOUSEY, _MOUSEBUTTON, _MOUSEWHEEL, _MOUSESHOW, _MOUSEHIDE, _MOUSEMOVE) donde encontrarás ejemplos con el código fuente:
    http://www.qb64.net/wiki/index.php/MOUSEINPUT

    Inform es un proyecto oficial de QB64 que implementa una herramienta RAD. Es decir, un diseñador de formularios con componentes visuales, que genera código QB64, y que se compila incluyendo la librería de Inform. En cierta forma pretende replicar lo que conocemos en Delphi/Lazarus, C++ Builder o Visual Basic, pero sobre QB. Es también parecido a Visual BASIC for DOS, sólo que las aplicaciones se ejecutan sobre modo gráfico:
    https://www.qb64.org/inform/

    Ya nos contarás como te ha ido y lo que estás intentando desarrollar.

  8. HUMBERTO GALVAN CALVILLO

    Te saludo de nuevo Guti, el pasado 29 de Marzo te comente que estaba programando en Qbasic y efectivamente he seguido, aunque mucha gente critique por el hecho de considerarlo un lenguaje prehistórico, la verdad que es atractivo, yo lo utilice hace como 20 años, pero he batallado para retomarlo, hace algunos días se me dificultó como aplicar el movimiento de mouse en el proyecto que estoy iniciando pero ya lo encontre con las ideas que me diste de _MOUSEX, y _MOUSEY, el programa que estoy diseñando es un control de almacen, ó un inventario, pero no recuerdo como presentar por pantalla el catalogo de 1000 productos que le aparezcan al usuario de 20 en 20, no te pido que me digas alguna rutina, solo quiero una idea, anticipadamente te agradezco la ayuda.

  9. Hola buenas, estoy progamando en Qb64 y teniendo una duda, he dado con tu pagina web. Quería si podrías ser tan amable de resolverme la duda (creo que puede ser fácil para ti y quitarte poco tiempo). Lo que quiero hacer es conectar una base de datos en XAMPP en otro ordenador con mysql_real_connect. Desde otro ordenador me puedo conectar phpmyadmin, pero no puedo con este programa en qb64 conectar. Muchas gracias por anticipado.

  10. Creo que has estado haciendo las pruebas correctas Javi C.. Tienes conectividad a MySQL desde otro equipo, y eso elimina que pueda ser problema de la cuenta limitada solamente a localhost, o de firewall/puertos.
    Sólo queda que el problema sea con el código, con las librerías de QB64 o con los credenciales que usas. Es difícil sin poder ver el código, y sin saber el error que te da.
    Siéntete libre de publicarlo aquí.

  11. Hola Javier. Soy compañero de Javi C., y los dos estamos bloqueados con la conexión de la base de datos XAMPP desde otro ordenador.

    Cuando se ejecuta el programa desde el ordenador(servidor) donde está la base de datos funciona perfectamente, pero si ejecuta desde otro ordenador y se sustituye 127.0.0.1 por la ip del servidor, no conecta.

    Gracias anticipadas.

    Es código seria este:

    DECLARE CUSTOMTYPE LIBRARY «mysql_helper»
    FUNCTION offset_to_string$ ALIAS offset_to_offset (BYVAL offset AS _OFFSET)
    FUNCTION offset_at_offset%& (BYVAL offset AS _OFFSET)
    END DECLARE

    ‘#### download mysql.dll from http://www.qb64.net/mysql.dll (~2MB) ####
    DECLARE DYNAMIC LIBRARY «mysql»
    FUNCTION mysql_init%& (BYVAL always_0 AS _OFFSET)
    ‘MYSQL *mysql_init(MYSQL *mysql)
    FUNCTION mysql_error$ (BYVAL mysql AS _OFFSET)
    ‘const char *mysql_error(MYSQL *mysql)
    FUNCTION mysql_get_client_info$
    ‘ Returns a string that represents the client library version
    ‘ const char *mysql_get_client_info(void)
    FUNCTION mysql_real_connect%& (BYVAL mysql AS _OFFSET, host AS STRING, user AS STRING, password AS STRING, db AS STRING, BYVAL port AS _UNSIGNED LONG, BYVAL unix_socket AS _OFFSET, BYVAL client_flag AS _UNSIGNED _OFFSET)
    FUNCTION mysql_real_connect_dont_open%& ALIAS mysql_real_connect (BYVAL mysql AS _OFFSET, host AS STRING, user AS STRING, password AS STRING, BYVAL db AS _OFFSET, BYVAL port AS _UNSIGNED LONG, BYVAL unix_socket AS _OFFSET, BYVAL client_flag AS _UNSIGNED LONG)
    ‘ MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
    ‘ The value of host may be either a host name or an IP address. If host is NULL or the string «localhost», a connection to the local host is assumed.
    ‘ db is the database name. If db is not NULL, the connection sets the default database to this value.
    ‘ If port is not 0, the value is used as the port number for the TCP/IP connection. Note that the host parameter determines the type of the connection.
    ‘ If unix_socket is not NULL, the string specifies the socket or named pipe to use. Note that the host parameter determines the type of the connection.
    ‘ The value of client_flag is usually 0, but can be set to a combination of the following flags to enable certain features.
    ‘ Return Value: A MYSQL* connection handle if the connection was successful, NULL if the connection was unsuccessful. For a successful connection, the return value is the same as the value of the first parameter.
    ‘*** REMEMBER, ALL STRINGS PASSED MUST BE NULL ‘+CHR$(0)’ TERMINATED ***
    SUB mysql_query (BYVAL mysql AS _OFFSET, mysql_command AS STRING)
    FUNCTION mysql_query& (BYVAL mysql AS _OFFSET, mysql_command AS STRING)
    ‘ int mysql_query(MYSQL *mysql, const char *stmt_str)
    ‘ Executes the SQL statement pointed to by the null-terminated string stmt_str. Normally, the string must consist of a single SQL statement without a terminating semicolon (“;”) or \g. If multiple-statement execution has been enabled,
    ‘Returns Zero if the statement was successful. Nonzero if an error occurred.
    ‘*** REMEMBER, ALL STRINGS PASSED MUST BE NULL ‘+CHR$(0)’ TERMINATED ***
    FUNCTION mysql_store_result%& (BYVAL mysql AS _OFFSET)
    ‘ MYSQL_RES *mysql_store_result(MYSQL *mysql)
    ‘ Returns a RESULT STRUCTURE
    FUNCTION mysql_num_fields~& (BYVAL result AS _OFFSET)
    ‘ unsigned int mysql_num_fields(MYSQL_RES *result)
    ‘ To pass a MYSQL* argument instead, use unsigned int mysql_field_count(MYSQL *mysql).
    ‘ Returns number of columns in result set
    FUNCTION mysql_num_rows&& (BYVAL result AS _OFFSET)
    ‘ my_ulonglong mysql_num_rows(MYSQL_RES *result)
    ‘ Returns the number of rows in the result set.
    FUNCTION mysql_fetch_row%& (BYVAL result AS _OFFSET)
    ‘ MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
    ‘ RETURNS A ROW STRUCTURE
    FUNCTION mysql_fetch_lengths%& (BYVAL result AS _OFFSET)
    ‘ unsigned long *mysql_fetch_lengths(MYSQL_RES *result)
    ‘ Returns the lengths of the columns of the current row within a result set.
    ‘ Returns a pointer to an array of lengths
    SUB mysql_close (BYVAL mysql AS _OFFSET)
    SUB mysql_free_result (BYVAL result AS _OFFSET)
    END DECLARE

    DIM SHARED conn AS _OFFSET
    DIM columns AS LONG
    REDIM SHARED DB_RESULT(columns, rows) AS STRING

    conn = mysql_init(0)
    IF conn = 0 THEN
    PRINT «No puedo iniciar MYSQL client!»: SLEEP (0)
    ELSE
    PRINT «conectado a MYSQL»
    END IF

    DIM conexion AS _OFFSET
    ‘*** Abrir Base de Datos ***
    conexion = mysql_real_connect(conn, «127.0.0.1», «root», «1451», «MERCA18», 0, 0, 0)
    IF conexion = 0 THEN PRINT «NO HE PODIDO CONECTAR CON EL SERVIDOR»: sleep 0

  12. En ese caso Juanjo Gómez, el problema no es el mismo que comentaba Javi C.. Él decía que desde otro ordenador sí había conectividad con phpMyAdmin.
    Por tanto el problema no es de código ni de las librerías de MySQL para QB64. El problema es de conectividad.
    Revisa el firewall/router/antivirus de la máquina cliente y servidor para verificar que el puerto esté abierto, y la configuración del usuario de MySQL para que acepte conexiones no solamente desde localhost.

  13. Gracias por la respuesta Javier.
    Posiblemente me haya explicado mal. Con el programa no nos podemos conectar, pero con phpmyadmin sí que podemos hacerlo desde el otro ordenador.
    ¿Habría que configurar algo en XAMPP para que se pudiera hacer la conexion con el programa?

  14. En ese caso Juanjo Gómez parece que ahora coincide con lo que indicaba Javi C. inicialmente. Si tenéis conectividad a MySQL desde otra máquina con phpMyAdmin, no parece que sea un problema de puertos cerrados o bloqueados.

    ¿Seguro que otra máquina es capaz de conectar al MySQL? ¿Estáis usando los mismos credenciales? Porque lo que veo en el código es que conecta a localhost, que es la versión que funciona.

  15. everardo flores gonzalez

    alguien que me pueda ayudar en qb64 , como puedo imprimir una imagen jpg o bmp a una impresora de ticket lo necesito imprimir es un LOGO antes del ticket y no se que comandos usar y como aplicarlo
    gracias

  16. Yo por ejemplo everardo flores gonzalez, pero deberás ser algo más específico acerca de la naturaleza del problema. ¿No sabes como enfocarlo? ¿Tienes código pero no funciona? ¿De qué parte tienes dudas? ¿Leer un JPEG o un BMP? ¿Imprimir un gráfico? ¿Es un problema de configuración de la impresora de tickets?

    De momento para ir avanzando, supongo que si llevas tiempo con el problema ya lo habrás hecho, mírate PRINTIMAGE.

Deja un comentario