Hola:
Como en las películas de antes, no recuerdo en qué peli sale, un ordenador que al imprimir mensajes, se oye un ruido por cada letra muy rápido.
Hice lo de imprimir cada letra en 10 milisegundos, 0.010 segundos.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading; // No olvidar.
namespace Texto_consola_CS
{
class Program
{
static void Main(string[] args)
{
Console.WindowWidth = 80;
Console.WindowHeight = 43;
Console.Title = "Título del programa en la ventana de la consola.";
Console.BackgroundColor = ConsoleColor.Black; // Fondo pantalla blanco.
Console.Clear(); // Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green; // Color texto azul.
string Cadena = @"El hombre moderno es un viajero que ha olvidado el lugar de donde va, y que
ha de volver a donde viene para saber a donde va.
No busques al amigo para matar las horas, sino búscale con horas para vivir.
Los amigos se convierten con frecuencia en ladrones de nuestro tiempo.
Es difícil decir quién hace el mayor daño: los enemigos con sus peores intenciones o los amigos con las mejores.
Recorre a menudo la senda que lleva al huerto de tu amigo, no sea que la maleza te impida ver el camino.";
Console.CursorVisible = true;
foreach (char Letra in Cadena)
{
Console.Write(Letra);
Thread.Sleep(2); //medio segundo
}
Console.Beep();
Console.ReadKey(); // Pulse cualquier tecla para salir.
}
}
}
Al final de impresión de oye un beep. No encuentro un vídeo de ejemplo por ahora para que vean a lo que me refiero. Cuando el hombre habla con el ordenador en la película y le responde con mesajes que se oye el ruido por cada letra que escriba en pantalla.
Si alguien sabe como se hace, lo explican, no he encontrado nada igual por Internet, lo más parecido es esto.
https://msdn.microsoft.com/es-es/library/4fe3hdb1%28v=vs.110%29.aspx
Pero no es lo mismo.
Cualquier información es de ayuda.
Saludos.
Me respondo a mi mismo.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading; // No olvidar.
namespace Texto_consola_CS
{
class Program
{
static void Main(string[] args)
{
Console.WindowWidth = 80;
Console.WindowHeight = 43;
Console.Title = "Título del programa en la ventana de la consola.";
Console.BackgroundColor = ConsoleColor.Black; // Fondo pantalla blanco.
Console.Clear(); // Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green; // Color texto azul.
string Cadena = @"El hombre moderno es un viajero que ha olvidado el lugar de su destino, y que
ha de volver a donde viene para saber a donde va.
No busques al amigo para matar las horas, sino búscale con horas para vivir.
Los amigos se convierten con frecuencia en ladrones de nuestro tiempo.
Es difícil decir quién hace el mayor daño: los enemigos con sus peores intenciones o los amigos con las mejores.
Recorre a menudo la senda que lleva al huerto de tu amigo, no sea que la maleza te impida ver el camino.";
Console.CursorVisible = true;
foreach (char Letra in Cadena)
{
Console.Write(Letra);
Console.Beep(500, 60);
}
Console.ReadKey(); // Pulse cualquier tecla para salir.
}
}
}
Saludos.
Hola
Interesante tu idea y buen aporte. Pero no me convence el sonido. Creo que solo debería hacer 'tic' cuando surja un carácter y no tan seguido. Similar a una máquina de escribir pero con sonido electrónico.
Usando tu código he hecho algún cambio (está en C#). A ver que te parece.
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
static class Module1
{
public static void Main()
{
Console.WindowWidth = 80;
Console.WindowHeight = 43;
Console.Title = "Título del programa en la ventana de la consola.";
Console.BackgroundColor = ConsoleColor.Black;
// Fondo pantalla blanco.
Console.Clear();
// Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green;
// Color texto azul.
string Cadena = string.Format("{1}{0}{0}{2}{0}{0}{3}{0}{0}{4}", Environment.NewLine, "CÓDIGO DE ACCESO:_ 59898OP-NEI56", "***CÓDIGO DE ACCESO DENEGADO***", "█ POR FAVOR, INTRODUZCA DE NUEVO EL CÓDIGO DE ACCESO █", "CÓDIGO DE ACCESO:_ ");
Console.CursorVisible = true;
foreach (char Letra in Cadena) {
//Espera 5 segundos
System.Threading.Thread.Sleep(0.09 * 1000);
if (Letra == Convert.ToChar(Environment.NewLine)) {
System.Threading.Thread.Sleep(0.75 * 1000);
//Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100);
// beep de salto de línea
}
Console.Write(Letra);
// Hacer sonido solo cuando el caracter sea distinto de espacio
if (string.IsNullOrWhiteSpace(Letra) == false) {
Console.Beep(500, 9);
}
}
Console.ReadKey();
// Pulse cualquier tecla para salir.
}
}
//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik
//Facebook: facebook.com/telerik
//=======================================================
Lo suyo sería también, poder cambiar el tipo de fuente.
Saludos
En vb.net
Module Module1
Sub Main()
Console.WindowWidth = 80
Console.WindowHeight = 43
Console.Title = "Título del programa en la ventana de la consola."
Console.BackgroundColor = ConsoleColor.Black
' Fondo pantalla blanco.
Console.Clear()
' Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green
' Color texto azul.
Dim Cadena As String = String.Format("{1}{0}{0}{2}{0}{0}{3}{0}{0}{4}", Environment.NewLine,
"CÓDIGO DE ACCESO:_ 59898OP-NEI56",
"***CÓDIGO DE ACCESO DENEGADO***",
"█ POR FAVOR, INTRODUZCA DE NUEVO EL CÓDIGO DE ACCESO █",
"CÓDIGO DE ACCESO:_ ")
Console.CursorVisible = True
For Each Letra As Char In Cadena
'Espera 5 segundos
System.Threading.Thread.Sleep(0.09 * 1000)
If Letra = CChar(Environment.NewLine) Then
System.Threading.Thread.Sleep(0.75 * 1000) 'Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100) ' beep de salto de línea
End If
Console.Write(Letra)
If String.IsNullOrWhiteSpace(Letra) = False Then ' Hacer sonido solo cuando el caracter sea distinto de espacio
Console.Beep(500, 9)
End If
Next
Console.ReadKey()
' Pulse cualquier tecla para salir.
End Sub
End Module
Por cierto la película a la que te refieres podría ser JUEGOS DE GUERRA (1983) (http://www.filmaffinity.com/es/film553168.html)
(ahora que recuerdo, creo que en esta película el ordenador hablaba ;D)
Código de acceso denegado... jaja. Bueno, me aburría y quise hacer una versión funcional. Qué recuerdos...
C#
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
static class Module1
{
public static void Main()
{
Console.WindowWidth = 80;
Console.WindowHeight = 43;
Console.Title = "Retro-Consola";
Console.BackgroundColor = ConsoleColor.Black;
// Fondo pantalla blanco.
Console.Clear();
// Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green;
// Color texto azul.
Console.CursorVisible = false;
1:
string Cadena = string.Format("{0}{1}{0}{0}{2}", Environment.NewLine, "█ POR FAVOR, INTRODUZCA EL CÓDIGO DE ACCESO █", "CÓDIGO DE ACCESO:_ ");
Mecanografiar(Cadena);
string Entrada = Console.ReadLine;
if (Entrada == 12345) {
Cadena = string.Format("{0}{1}{0}{0}{2}{0}{3}{0}{4}", Environment.NewLine, "*** CÓDIGO DE ACCESO ACEPTADO ***", "████████████████████████████████████████", "█ BIENVENIDO DOCTOR FRANKESTEIN █", "████████████████████████████████████████");
Mecanografiar(Cadena);
} else {
Cadena = string.Format("{0}{1}{0}", Environment.NewLine, "*** CÓDIGO DE ACCESO DENEGADO ***");
Mecanografiar(Cadena);
goto 1;
}
Console.ReadKey();
}
public static void Mecanografiar(string Cadena)
{
foreach (char Letra in Cadena) {
//Espera 5 segundos
if (Letra == Convert.ToChar(Environment.NewLine)) {
System.Threading.Thread.Sleep(0.75 * 1000);
//Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100);
// beep de salto de línea
} else {
System.Threading.Thread.Sleep(0.09 * 1000);
Console.Write(Letra);
// Hacer sonido solo cuando el caracter sea distinto de espacio
if (string.IsNullOrWhiteSpace(Letra) == false) {
Console.Beep(500, 9);
}
}
}
}
}
//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik
//Facebook: facebook.com/telerik
//=======================================================
VBNET
Module Module1
Sub Main()
Console.WindowWidth = 80
Console.WindowHeight = 43
Console.Title = "Retro-Consola"
Console.BackgroundColor = ConsoleColor.Black' Fondo pantalla blanco.
Console.Clear()' Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green' Color texto azul.
Console.CursorVisible = False
1:
Dim Cadena As String = String.Format("{0}{1}{0}{0}{2}", Environment.NewLine,
"█ POR FAVOR, INTRODUZCA EL CÓDIGO DE ACCESO █",
"CÓDIGO DE ACCESO:_ ")
Mecanografiar(Cadena)
Dim Entrada As String = Console.ReadLine
If Entrada = 12345 Then
Cadena = String.Format("{0}{1}{0}{0}{2}{0}{3}{0}{4}", Environment.NewLine,
"*** CÓDIGO DE ACCESO ACEPTADO ***",
"████████████████████████████████████████",
"█ BIENVENIDO DOCTOR FRANKESTEIN █",
"████████████████████████████████████████")
Mecanografiar(Cadena)
Else
Cadena = String.Format("{0}{1}{0}", Environment.NewLine,
"*** CÓDIGO DE ACCESO DENEGADO ***")
Mecanografiar(Cadena)
GoTo 1
End If
Console.ReadKey()
End Sub
Sub Mecanografiar(ByVal Cadena As String)
For Each Letra As Char In Cadena
'Espera 5 segundos
If Letra = CChar(Environment.NewLine) Then
System.Threading.Thread.Sleep(0.75 * 1000) 'Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100) ' beep de salto de línea
Else
System.Threading.Thread.Sleep(0.09 * 1000)
Console.Write(Letra)
If String.IsNullOrWhiteSpace(Letra) = False Then ' Hacer sonido solo cuando el caracter sea distinto de espacio
Console.Beep(500, 9)
End If
End If
Next
End Sub
End Module
Hola:
Que buena pinta tiene el programa. Muchas gracias campeón, lo voy a probar y te cuento.
Que recuerdos. Este si que es una buena peli de hacker básico pero buena. La más nueva que salió hace poco me pareció mala en muchos aspectos, menos cuando salen cosas de programación.
(http://coliseodigital.com/wp-content/uploads/2013/05/juegos_de_guerra.jpg)
Vi la segunda parte y no es lo mismo. Lo bueno que sale el ordenador el 1.
(http://www.hispashare.com/images/titles/4664/cover.jpg)
(http://picandocodigo.net/wp-content/uploads/2008/06/wargames-03.jpg)
Ojalá salga el 3.
Probando el último código en C#, lo primero me da errores por todas partes, y nunca había visto usar goto que se aconseja no usarlo en C# ni en Visual Basic para evitar malos hábitos.
Saludos.
Cita de: Meta en 27 Febrero 2016, 15:30 PM
Probando el último código en C#, lo primero me da errores por todas partes, y nunca había visto usar goto que se aconseja no usarlo en C# ni en Visual Basic para evitar malos hábitos.
Saludos.
:P Normal, ni siquiera lo he testeado jaja. Simplemente he usado una conversión online y luego lo pegué.
De todos modos básicamente lo que interesa es la función
Mecanografiar para hacer los efectos de sonido.
En cuanto el uso de GOTO, antiguamente en Basic se usaba muchísimo, y en tal caso no veo porqué no. Yo tuve un ordenador Sharp que funcionaba con Basic y un Commodore64 y era bastante habitual.
Saludos
Pues, así es. En C# no funciona :-[
Para empezar C# no permite esto (y supongo que tampoco en C++):
System.Threading.Thread.Sleep(0.09 * 1000);
Es decir, usar un valor temporal inferior a un segundo de este modo (0.09 * 1000). En lugar de eso simplemente poner, por ejemplo:
System.Threading.Thread.Sleep(100);
Esto es imprescindible para conseguir el efecto de tecla (tac, tac, tac,...) pues, sólo hace un tic similar a una tecla, sin determinarse claramente que sonido suena.
[CORREGIDO EN C#]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
public static void Main()
{
Console.WindowWidth = 80;
Console.WindowHeight = 43;
Console.Title = "Retro-Consola";
Console.BackgroundColor = ConsoleColor.Black;
// Fondo pantalla blanco.
Console.Clear();
// Limpiar pantalla.
Console.ForegroundColor = ConsoleColor.Green;
// Color texto azul.
Console.CursorVisible = false;
j1:;
string Cadena = string.Format("{0}{1}{0}{0}{2}", Environment.NewLine, "█ POR FAVOR, INTRODUZCA EL CÓDIGO DE ACCESO █", "CÓDIGO DE ACCESO:_ ");
Mecanografiar(Cadena);
string Entrada;
Entrada = Console.ReadLine();
if (Entrada == "12345") {
Cadena = string.Format("{0}{1}{0}{0}{2}{0}{3}{0}{4}", Environment.NewLine, "*** CÓDIGO DE ACCESO ACEPTADO ***", "████████████████████████████████████████", "█ BIENVENIDO DOCTOR FRANKESTEIN █", "████████████████████████████████████████");
Mecanografiar(Cadena);
} else {
Cadena = string.Format("{0}{1}{0}", Environment.NewLine, "*** CÓDIGO DE ACCESO DENEGADO ***");
Mecanografiar(Cadena);
goto j1;
}
Console.ReadKey();
}
public static void Mecanografiar(string Cadena)
{
foreach (char Letra in Cadena)
{
if ((Letra) == Convert.ToChar(ConsoleKey.Enter))
{
System.Threading.Thread.Sleep(750);
//Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100);
// beep de salto de línea
}
else
{
System.Threading.Thread.Sleep(90);
Console.Write(Letra);
// Hacer sonido solo cuando el caracter sea distinto de espacio
if ((Letra) != Convert.ToChar(ConsoleKey.Spacebar))
{
Console.Beep(500, 9);
}
}
}
}
}
}
La función para crear el efecto:
public static void Mecanografiar(string Cadena)
{
foreach (char Letra in Cadena)
{
if ((Letra) == Convert.ToChar(ConsoleKey.Enter))
{
System.Threading.Thread.Sleep(750);
//Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100);
// beep de salto de línea
}
else
{
System.Threading.Thread.Sleep(90);
Console.Write(Letra);
// Hacer sonido solo cuando el caracter sea distinto de espacio
if ((Letra) != Convert.ToChar(ConsoleKey.Spacebar))
{
Console.Beep(500, 9);
}
}
}
}
Para modificar la velocidad cambia el valor de 90 a menos o más según prefieras:
System.Threading.Thread.Sleep(90)
En un principio puse 130, pero es demasiado lento. Creo que 90 está bien.
Saludos
Puede usarse
TimeSpan en lugar de usarse
Sleep del siguiente modo:
TimeSpan interval = new TimeSpan(0, 0, 0, 0, 90);
Thread.Sleep(interval);
Ejemplo:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string cadena = "Ejemplo de como usar TimeSpan..." +
Environment.NewLine +
"... En lugar de usar Speep";
Mecanografiar(cadena);
}
public static void Mecanografiar(string Cadena)
{
foreach (char Letra in Cadena)
{
if ((Letra) == Convert.ToChar(ConsoleKey.Enter))
{
TimeSpan interval = new TimeSpan(0, 0, 0, 0, 500);
Thread.Sleep(interval);
//System.Threading.Thread.Sleep(750);
//Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100);
// beep de salto de línea
}
else
{
TimeSpan interval = new TimeSpan(0, 0, 0, 0, 90);
Thread.Sleep(interval);
// System.Threading.Thread.Sleep(90);
Console.Write(Letra);
// Hacer sonido solo cuando el caracter sea distinto de espacio
if ((Letra) != Convert.ToChar(ConsoleKey.Spacebar))
{
Console.Beep(500, 9);
}
}
}
}
}
}
¡¡¡¡Holaaaaaaaaaaaaaa!!!!
El último código lo hicieste de p**a madre con pausas en los espacios y todo.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string cadena = "Ejemplo de como usar TimeSpan..." +
Environment.NewLine +
"... En lugar de usar Speep";
Mecanografiar(cadena);
}
public static void Mecanografiar(string Cadena)
{
foreach (char Letra in Cadena)
{
if ((Letra) == Convert.ToChar(ConsoleKey.Enter))
{
TimeSpan interval = new TimeSpan(0, 0, 0, 0, 500);
Thread.Sleep(interval);
System.Threading.Thread.Sleep(750);
//Espera 0.75 segundos antes de hacer el salto de línea
Console.Beep(600, 100);
// beep de salto de línea
}
else
{
TimeSpan interval = new TimeSpan(0, 0, 0, 0, 90);
Thread.Sleep(interval);
// System.Threading.Thread.Sleep(90);
Console.Write(Letra);
// Hacer sonido solo cuando el caracter sea distinto de espacio
if ((Letra) != Convert.ToChar(ConsoleKey.Spacebar))
{
Console.Beep(500, 9);
}
}
}
}
}
}
Sólo me falta odificar los colores y hacer lo que me da la gana con tu estilo.
Por cierto, me gustó mucho esto.
(http://fotos.subefotos.com/df2095fc38b5540966b1c6939ec118b7o.png)
Me recordaste los viejos tiempos. ;)
Hay partes del código que no entiendo, nuevo para mi a la hora de presentar textos en pantalla como este pedazo de código.
Cadena = string.Format("{0}{1}{0}{0}{2}{0}{3}{0}{4}", Environment.NewLine, "*** CÓDIGO DE ACCESO ACEPTADO ***", "████████████████████████████████████████", "█ BIENVENIDO DOCTOR FRANKESTEIN █", "████████████████████████████████████████");
Mecanografiar(Cadena);
El string.Format.
¿Es necesario usar eso así en vez la consola Console.WreiteLine directamente?
Saludos.
Hola Meta
El string.Format.
¿Es necesario usar eso así en vez la consola Console.WreiteLine directamente?
Hombre, necesario no es, pero simplifica bastante la labor, pues {0} en este caso representa Environment.NewLine, y no tengo que estar todo el rato escribiendo Environment.NewLine.
Ejemplo:
Cadena = string.Format("{0} {1} {0} {2} ", "#0", "#1" ,"#2");,
{0} Representa "#0"
{1} Representa "#1"
{2} Representa "#2"
"Cadena" devuelve:
#0 #1 #0 #2
Por cierto, como ves GeShi para C# no acepta carácteres especiales ASCII como este █ = (Alt + 219). Los cuales te serán muy útiles para conseguir el efecto retro, ya que se usaban estos marcos ╔═════════════════════╗ en lugar de las ventanas o cuadros de mensajes actuales.
Carácteres ASCII (http://www.internetsecurityguru.com/better_passowrds.html)
Mientras experimentaba con WriteLine para obtener el valor string de lo escrito en consola, es decir pasarlo a una variable string, he querido crear el efecto de highlightb del texto pero no lo consigo. A ver si alguien sabe como...
(http://programarcadegames.com/chapters/05_intro_to_graphics/apple3screen.png)
Podría ser algo así pero es un palo:
string NL = Environment.NewLine;
string T1 = "Adt Configuration";
string T2= "DISK SLOT";
string T3 = "DISK SLOT 2";
T1 = T1.ToUpper();
Console.BackgroundColor=ConsoleColor.Green;
Console.ForegroundColor = ConsoleColor.Black;
Console.Write("{1} {0}", NL, T1);
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("{0}", NL);
Console.Write("{0} ", T2);
Console.BackgroundColor = ConsoleColor.Green;
Console.ForegroundColor = ConsoleColor.Black;
Console.Write("{0} ", "1".PadLeft(5));
Hola:
Ahora lo entiendo. ;)
Muchas gracias por la ayuda mi muy distinguido amigo. ;)
En en ejemplo con TimeSpan se me olvidó eliminar la línea 28 :-\
Ya lo he quitado
//System.Threading.Thread.Sleep(750);
Creo que no comentaré nada más jeje
saludos ;)
Hola
Solo vengo a aclarar una duda que ha surgido en este post a la cual no se le ha dado una respuesta muy acertada.
La instrucción Goto está deprecada desde hace décadas, Visual Basic es un lenguaje que nació de hace décadas, y lo que sigue persistiendo en Visual Basic.Net/C# solo es por mera compatibilidad para aquellos que no quieran perder las malas costumbres al migrar a este lenguaje.
Efectivamente la utilización de la instrucción Goto es totalmente irrecomendable tanto por Microsoft en la MSDN así como de forma no-oficial en cualquier otro lenguaje que soporte Goto y por cualquier programador con los conocimientos suficientes para entender lo que su uso implica, esto se debe a muchos motivos, pero la razón principal es que al utilizarlo estamos destrozando por completo el flujo de control de cualquier algoritmo, el uso de Goto tiende a generar un código spaguetti y esto imposibilita o dificulta la correcta depuración del código.
La instrucción Goto es ineficiente, peligrosa e insegura, y actualmente es algo innecesario en un lenguaje como Vb.Net/C#, ya que .Net Framework nos ofrece una solución eficiente para cualquier tipo de situación, como por ejemplo encapsular el algoritmo en un búcle, o en un bloque try/catch, o simplemente llamar a un método, el tipo de solución más apta dependerá de las circunstancias de nuestro algoritmo claro está.
TL/DR:
Desgraciadamente Microsoft utiliza muchísimo la instrucción Goto en el código fuente de la class Microsoft.VisualBasic (funciones Left, Mid, etc...) y ese es uno de los motivos por los que siempre desaconsejo utilizar esta Class de compatibildiad que no aporta ningún beneficio al programador, no solo por eso, sino por que la lógica programada está deprecada, es de hace décadas, sin actualizaciones de rendimiento, son algoritmos lentos y sucios, y hay alternativas eficientes para cualqueir miembro de esa Class en el resto de la librería de Classes de .Net framework.
Saludos!
Cita de: Eleкtro en 1 Marzo 2016, 11:10 AM
Solo vengo a aclarar una duda que ha surgido en este post a la cual no se le ha dado una respuesta muy correcta.
Gracias
Elektro por la aclaración.
Como he dicho, se usaba antiguamente. Me cito a mi mismo:
En cuanto el uso de GOTO, antiguamente en Basic se usaba muchísimo, y en tal caso no veo porqué no. Yo tuve un ordenador Sharp que funcionaba con Basic y un Commodore64 y era bastante habitual.
Con "y en tal caso no veo porqué no" quiero decir que para el sencillo ejemplo que he puesto y además emulando la consola retro, creo que se puede utilizar. Vamos que no creo que vaya a explotar el ordenador :xD
Lo que interesaba es crear el efecto retro de sonido que pedía Meta (en el que el
GOTO no interviene).
Solo quería aclarar eso.
Saludos.
Cita de: Eleкtro en 1 Marzo 2016, 11:10 AM
Efectivamente la utilización de la instrucción Goto es totalmente irrecomendable tanto por Microsoft en la MSDN así como de forma no-oficial en cualquier otro lenguaje que soporte Goto y por cualquier programador con los conocimientos suficientes para entender lo que su uso implica[...]
No comparto que el Goto no se recomiende en cualquier lenguaje de programación. El GOTO que se uso mucho es en ASM de los PIC. Lo usas si o si.
; ZONA DE DATOS *******************************************************
LIST P=16F887
INCLUDE <P16F887.INC>
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
__IDLOCS 0x1234
CBLOCK 0x20
TeclaPulsada ; Va a guardar el contenido de la tecla pulsada.
MensajeApuntado ; Va a guarda la dirección del mensaje apuntado.
Relays ; Estado de los relays
Estado ; Estado general
ENDC
#DEFINE PEntradasB PORTB ; Define puerto de salidas.
#DEFINE EntradaR1B 0 ; Define dónde se sitúa cada salidas.
#DEFINE EntradaR2B 1
#DEFINE EntradaR3B 2
#DEFINE EntradaR4B 3
#DEFINE EntradaR5B 4
#DEFINE EntradaR6B 5
#DEFINE EntradaR7B 6
#DEFINE EntradaR8B 7
#DEFINE PSalidasD PORTD
#DEFINE SalidaR1D 0
#DEFINE SalidaR2D 1
#DEFINE SalidaR3D 2
#DEFINE SalidaR4D 3
#DEFINE SalidaR5D 4
#DEFINE SalidaR6D 5
#DEFINE SalidaR7D 6
#DEFINE SalidaR8D 7
TECLA_RELE_1_ON EQU 'q' ; Código de las teclas utilizadas.
TECLA_RELE_1_OFF EQU 'a'
TECLA_RELE_2_ON EQU 'w'
TECLA_RELE_2_OFF EQU 's'
TECLA_RELE_3_ON EQU 'e'
TECLA_RELE_3_OFF EQU 'd'
TECLA_RELE_4_ON EQU 'r'
TECLA_RELE_4_OFF EQU 'f'
TECLA_RELE_5_ON EQU 't'
TECLA_RELE_5_OFF EQU 'g'
TECLA_RELE_6_ON EQU 'y'
TECLA_RELE_6_OFF EQU 'h'
TECLA_RELE_7_ON EQU 'u'
TECLA_RELE_7_OFF EQU 'j'
TECLA_RELE_8_ON EQU 'i'
TECLA_RELE_8_OFF EQU 'k'
TECLA_INICIO EQU 'z'
TECLA_PARADA EQU ' ' ; Código de la tecla espaciadora, (hay un espacio,
; tened cuidado al teclear el programa).
TECLA_INFO EQU 'n'
ENTER EQU 0x0A ; Código de tecla "Enter" o "Retorno de Carro".
CAMBIO_LINEA EQU 0x0D ; Código para el cambio de línea.
ORG 0x2100 ; Corresponde a la dirección 0 de la zona EEPROM
; de datos.
DE 0x00,2,3
;****************************************************************************
;* ZONA DE CODIGOS *
;****************************************************************************
;****************************************************************************
;* Rutina Principal *
;****************************************************************************
ORG 0x00
goto Inicio
ORG 4 ; Aquí se sitúa el vector de interrupción para
goto LeeEntradasVisualiza ; atender las subrutinas de interrupción.
Inicio
call LCD_Inicializa ; Inicializa el display LCD
call RS232_Inicializa ; Inicializa RS232.
bsf PEntradasB,EntradaR1B
bsf PEntradasB,EntradaR2B
bsf PEntradasB,EntradaR3B
bsf PEntradasB,EntradaR4B
bsf PEntradasB,EntradaR5B
bsf PEntradasB,EntradaR6B
bsf PEntradasB,EntradaR7B
bsf PEntradasB,EntradaR8B
bcf PSalidasD,SalidaR1D
bcf PSalidasD,SalidaR2D
bcf PSalidasD,SalidaR3D
bcf PSalidasD,SalidaR4D
bcf PSalidasD,SalidaR5D
bcf PSalidasD,SalidaR6D
bcf PSalidasD,SalidaR7D
bcf PSalidasD,SalidaR8D
BANKSEL CM1CON0
movlw b'00000111'
movwf CM1CON0
movwf CM2CON0
movwf CM2CON1
BANKSEL ANSEL
clrf ANSEL
clrf ANSELH
BANKSEL TRISB
movlw b'11111111'
movwf TRISB
clrw
clrf TRISD
BANKSEL PORTD
call RS232_LineasBlanco ; Visualiza unas cuantas líneas en blanco
call RS232_LineasBlanco ; para limpiar la pantalla.
movlw b'10001000' ; Habilita la interrupción RBI y la general.
movwf INTCON
Principal ; apagadas.
sleep
goto Principal ; Loop Infinito
;****************************************************************************
;* Mensajes *
;****************************************************************************
Mensajes
addwf PCL,F
MensajeParado
DT "Sistema DESACTIVADO ", 0x00
Mensaje_Reles
DT " 1 2 3 4 5 6 7 8 RL ", 0x00
Mensaje_ON
DT " 1", 0x00
Mensaje_OFF
DT " O", 0x00
Mensaje_Cambiolinea
DT ENTER, CAMBIO_LINEA, 0x00
Mensaje_Mostrarlinea
DT "----------------", 0x00
Mensaje_Info
DT "n", 0x00
; DT "FirmWare v2.15 "
; DT ENTER, CAMBIO_LINEA
; call LCD_Linea2
; DT " PIC16F887 "
; DT ENTER, CAMBIO_LINEA
; call Retardo_2s
; call LCD_Linea1
; DT " metaconta "
; DT ENTER, CAMBIO_LINEA
; call LCD_Linea2
; DT " @gmail.com ", 0x00
; call Retardo_2s
Mensaje_Activar
DT " Todos ACTIVOS ", 0x00
Mensaje_IN
DT " IN", 0x00
Mensaje_OUT
DT " OUT", 0x00
Mensaje_Avisos
DT "*** ALARMA ***", 0x00
MensajeEntradas
DT ENTER, CAMBIO_LINEA
DT " 1 2 3 4 5 6 7 8 IN"
DT ENTER, CAMBIO_LINEA
DT "-------------------"
DT ENTER, CAMBIO_LINEA, 0x00
FinTablaASCII
;****************************************************************************
; Interrupción
;****************************************************************************
;****************************************************************************
; Subrutina
;****************************************************************************
; btfss PEntradasC,EntradaR1C ; ¿Bit 0 del PORTA es "1"?
; goto D1_OFF
; bsf PSalidasD,SalidaR1D
; goto Principal
;D1_OFF
; bcf PSalidasD,SalidaR1D
LeeEntradasVisualiza
call RS232_LineasBlanco
movlw MensajeEntradas ; Nombre de las entradas.
call RS232_Mensaje ; Lo visualiza en el ordenador.
LeeEntrada1
btfss PEntradasB,EntradaR1B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada1Cerrado ; No, está cerrada.
bsf PSalidasD,SalidaR1D
call VisualizaAbierto1
goto LeeEntrada2
Entrada1Cerrado
bcf PSalidasD,SalidaR1D
call VisualizaCerrado1
LeeEntrada2
btfss PEntradasB,EntradaR2B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada2Cerrado ; No, está cerrada.
call VisualizaAbierto2
goto LeeEntrada3
Entrada2Cerrado
call VisualizaCerrado2
LeeEntrada3
btfss PEntradasB,EntradaR3B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada3Cerrado ; No, está cerrada.
call VisualizaAbierto3
goto LeeEntrada4
Entrada3Cerrado
call VisualizaCerrado3
LeeEntrada4
btfss PEntradasB,EntradaR4B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada4Cerrado ; No, está cerrada.
call VisualizaAbierto4
goto LeeEntrada5
Entrada4Cerrado
call VisualizaCerrado4
LeeEntrada5
btfss PEntradasB,EntradaR5B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada5Cerrado ; No, está cerrada.
call VisualizaAbierto5
goto LeeEntrada6
Entrada5Cerrado
call VisualizaCerrado5
LeeEntrada6
btfss PEntradasB,EntradaR6B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada6Cerrado ; No, está cerrada.
call VisualizaAbierto6
goto LeeEntrada7
Entrada6Cerrado
call VisualizaCerrado6
LeeEntrada7
btfss PEntradasB,EntradaR7B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada7Cerrado ; No, está cerrada.
call VisualizaAbierto7
goto LeeEntrada8
Entrada7Cerrado
call VisualizaCerrado7
LeeEntrada8
btfss PEntradasB,EntradaR8B ; ¿Entrada = 1?, ¿Entrada = Abierta?
goto Entrada8Cerrado ; No, está cerrada.
call VisualizaAbierto8
goto FinVisualiza
Entrada8Cerrado
call VisualizaCerrado8
FinVisualiza
call RS232_LineasBlanco
bcf INTCON,RBIF ; Limpia el flag de reconocimiento de la
retfie
;----------------------------------------------------------------------------------------
VisualizaAbierto1
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto2
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto3
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto4
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto5
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto6
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto7
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaAbierto8
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_ON ; Visualiza el mensaje "Abierto"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado1
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado2
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado3
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado4
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado5
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado6
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado7
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return
VisualizaCerrado8
call LCD_Linea2 ; Seleccionar la línea 2.
movlw Mensaje_OFF ; Visualiza el mensaje "Cerrado"
call RS232_Mensaje ; en el HyperTerminal.
return ; interrupción.
; ---------------------------------------------------------------------------
IF (FinTablaASCII>0xFF)
ERROR "¡CUIDADO!: La tabla ha superado el tamaño de los"
MESSG "primeros 256 bytes de memoria ROM. No funcionará correctamente."
ENDIF
INCLUDE <RS232.INC>
INCLUDE <RS232MEN.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <RETARDOS.INC>
INCLUDE <EEPROM.INC>
END
GOTO para asm o ensamblador de PIC, 8085, 8086, 8088 y demás, se usa obligado por el cual está diseñado así, para lenguajes de bajo nivel. Para alto nivel como explica nuestro amigo, es como dice.
Gracias por la explicación.
Cita de: Meta en 1 Marzo 2016, 14:24 PMNo comparto que el Goto no se recomiende en cualquier lenguaje de programación. El GOTO que se uso mucho es en ASM de los PIC. Lo usas si o si.
GOTO para asm o ensamblador de PIC, 8085, 8086, 8088 y demás, se usa obligado por el cual está diseñado así, para lenguajes de bajo nivel. Para alto nivel como explica nuestro amigo, es como dice.
Por supuesto, se entiende que lo que he dicho se aplica a cualquier lenguaje cuya utilización no sea
obligatoria, donde no exista una alternativa en el paradigma bajo el que nos permite programar ese lenguaje.
En
Batch por ejemplo también hay que utilizar Goto si o si, sería absurdo pensar que al utilizarlo en estas circunstancias es seguir malos hábitos de programación, ya que no hay elección, estamos limitados.
Como ya dije, el uso de Goto está totalmente considerado deprecado e irrecomendable desde hace décadas para todos los lenguajes de programación bajo el que nos encontremos, esto se aplica a los lenguajes actuales de alto nivel con lo s paradigmas de mayor abstracción, los lenguajes que están en continuidad, vaya, te recuerdo que ASM apareció en el año 1949, es normal pensar que FASM, MASM, Objective ASM y todos esos tengan compatibilidad con Goto y dispongan o no de una alternativa a su utilización.
Los inconvenientes del uso de GoTo se conocen desde tiempos remotos de la programación, como prueba este extracto de la declaración "
Go To Statement Considered Harmful" de
Edsger W. Dijkstra publicada en el año
1968:
Cita de: http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html"The unbridled use of the go to statement has as an immediate consequence that it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress. ... The go to statement as it stands is just too primitive, it is too much an invitation to make a mess of one's program."
Y algunos de los métodos propuestos en el año 1990 que nos indica la wikipedia en la documentación del paradigma de programación estructurada:
Cita de: https://en.wikipedia.org/wiki/Structured_program_theoremUp to 1990 there were quite a few proposed methods for eliminating gotos from existing program, while preserving most of their structure. The various approaches to this problem also proposed several notions of equivalence, which are stricter than simply Turing equivalence, in order to avoid output like the folk theorem discussed above. The strictness of the chosen notion of equivalence dictates the minimal set of control flow structures needed. The 1988 JACM paper by Lyle Ramshaw surveys the field up to that point, as well proposing its own method. Ramshaw's algorithm was used for example in some Java decompilers because the Java virtual machine code has branch instructions with targets expressed as offsets, but the high-level Java language only has multi-level break and continue statements. Ammarguellat (1992) proposed a transformation method that goes back to enforcing single-exit.
Esto es lo que nos aconseja la MSDN:
Cita de: https://msdn.microsoft.com/en-us/library/69whc95c.aspx"GoTo statements can make code difficult to read and maintain. Whenever possible, use a control structure instead."
( hay que entender que el artículo está escrito para todo el público, por eso debemos cambiar las palabras "
Whenever possible" por "
Whenever you don't know other way to do". )
Soluciones al uso del Goto en C#/Vb.Net ya las expliqué en mi comentario anterior.
Saludos!