afegit intèrpret ascii, doc d'API i fonts Pascal originals

This commit is contained in:
2026-05-15 09:56:56 +02:00
parent 6d6ee4b635
commit 503d25440b
61 changed files with 10929 additions and 0 deletions
+271
View File
@@ -0,0 +1,271 @@
# ASCII — Referencia del intérprete Lua
Documento extraído del código fuente en `c:/mingw/gitea/ascii/` (principalmente `ascii.cpp`, `lua.cpp`, `play.cpp`, `ascii.h`). Sirve como guía para portar Pepe Runner desde Turbo Pascal a Lua.
> Versión analizada del intérprete: v0.6.1 aprox (según el mensaje del boot ROM en `lua.cpp`).
---
## 1. Modelo de ejecución
Cada juego/programa es **un solo fichero `.lua`** que define dos funciones globales:
```lua
function init()
-- se llama una sola vez al arrancar
end
function update()
-- se llama cada frame (~60 FPS, vsync)
end
```
- El intérprete se invoca como `ascii.exe nombre_juego.lua`. Si no se pasa argumento, intenta cargar `game.lua`.
- También se puede **arrastrar y soltar** un `.lua` sobre la ventana para cargarlo.
- **F5** reinicia el juego (re-llama a `init()` y vuelve a empezar el bucle).
- **ESC** pausa la ejecución y abre una consola de depuración (`> ` prompt). Los comandos `run` y `cont` la cierran. Comandos prefijados con `?` evalúan e imprimen (ej.: `?1+1`).
- Se usa la versión estándar de Lua que está vendorizada en `ascii/lua/` (con `luaL_openlibs`), así que están disponibles `string`, `math`, `table`, etc.
---
## 2. Modos de pantalla — `mode(n)`
| Modo | Resolución carácter | Resolución pixel | Notas |
|------|--------------------:|-----------------:|-------|
| 0 | 80 × 30 | 640 × 240 | Color único global (no por-carácter) — usado para depuración / texto. `current_color` aplica a toda la pantalla. |
| 1 | 40 × 30 | 320 × 240 | **Modo por defecto.** Color por carácter. |
| 2 | 20 × 15 | 160 × 120 | Mitad de resolución. Cómodo para tiles grandes (ej.: sokoban). |
| 3 | 32 × 24 | 256 × 192 | Estilo "ZX Spectrum" (con bordes anchos). |
Cada carácter es **8×8 píxeles**. Los gráficos son texto coloreado, no píxeles libres — el "lienzo" es una matriz de celdas (carácter + atributo de color).
---
## 3. Paleta de colores (16, CGA/EGA)
Constantes Lua predefinidas (`lua.cpp` líneas 610-625):
| Código | Constante | Aprox. |
|-------:|------------------------|---------------|
| 0 | `COLOR_BLACK` | #000000 |
| 1 | `COLOR_BLUE` | #0000AA |
| 2 | `COLOR_GREEN` | #00AA00 |
| 3 | `COLOR_CYAN` | #00AAAA |
| 4 | `COLOR_RED` | #AA0000 |
| 5 | `COLOR_MAGENTA` | #AA00AA |
| 6 | `COLOR_BROWN` | #AA5500 |
| 7 | `COLOR_LIGHT_GRAY` | #AAAAAA |
| 8 | `COLOR_DARK_GRAY` | #555555 |
| 9 | `COLOR_LIGHT_BLUE` | #5555FF |
| 10 | `COLOR_LIGHT_GREEN` | #55FF55 |
| 11 | `COLOR_LIGHT_CYAN` | #55FFFF |
| 12 | `COLOR_LIGHT_RED` | #FF5555 |
| 13 | `COLOR_LIGHT_MAGENTA` | #FF55FF |
| 14 | `COLOR_YELLOW` | #FFFF55 |
| 15 | `COLOR_WHITE` | #FFFFFF |
El atributo de color de una celda es 1 byte: nibble bajo = INK (tinta), nibble alto = PAPER (fondo).
---
## 4. API — Funciones expuestas a Lua
### Pantalla y color
| Función | Descripción |
|---------|-------------|
| `mode(n)` | Cambia modo de pantalla (0-3) y hace cls. |
| `cls([chr=32])` | Limpia con el carácter dado (32 = espacio). En modo ≠0 además rellena el color attr. |
| `ink(c)` | Color de tinta (0-15). |
| `paper(c)` | Color de fondo (0-15). |
| `border(c)` | Color del borde de la ventana. |
| `color(ink, paper, [border])` | Combina los tres. |
| `locate(x, y)` | Posiciona cursor en celda (x, y). |
| `print(str, [x, y])` | Imprime `str` (sin salto de línea). Si se dan x,y, primero hace `locate`. |
| `crlf()` | CR + LF (mueve cursor a inicio de siguiente línea). |
### Entrada
| Función | Descripción |
|---------|-------------|
| `btn(k)` | `true` si la tecla `k` está pulsada *en este frame* (estado SDL_GetKeyboardState). |
| `btnp(k)` | `true` solo en el frame en que la tecla se pulsa (edge). |
| `mousex()` / `mousey()` | Posición del ratón en **coordenadas de carácter** (ya escalado al modo). |
| `mousewheel()` | Delta de la rueda en este frame. |
| `mousebutton(i)` | `true` si el botón `i` está pulsado (1=izq, 2=medio, 3=der; usa `SDL_BUTTON(i)`). |
Códigos de tecla — todos definidos como globales `KEY_*` en Lua. Lista completa (de `lua.cpp` 502-608):
```
KEY_A..KEY_Z = 4..29
KEY_1..KEY_0 = 30..39 (1=30, 2=31, ..., 9=38, 0=39)
KEY_RETURN=40 KEY_ESCAPE=41 KEY_BACKSPACE=42 KEY_TAB=43 KEY_SPACE=44
KEY_MINUS=45 KEY_EQUALS=46 KEY_LEFTBRACKET=47 KEY_RIGHTBRACKET=48
KEY_BACKSLASH=49 KEY_NONUSHASH=50 KEY_SEMICOLON=51 KEY_APOSTROPHE=52
KEY_GRAVE=53 KEY_COMMA=54 KEY_PERIOD=55 KEY_SLASH=56 KEY_CAPSLOCK=57
KEY_F1..KEY_F12 = 58..69
KEY_PRINTSCREEN=70 KEY_SCROLLLOCK=71 KEY_PAUSE=72
KEY_INSERT=73 KEY_HOME=74 KEY_PAGEUP=75 KEY_DELETE=76 KEY_END=77 KEY_PAGEDOWN=78
KEY_RIGHT=79 KEY_LEFT=80 KEY_DOWN=81 KEY_UP=82
KEY_NUMLOCKCLEAR=83 KEY_KP_DIVIDE=84 KEY_KP_MULTIPLY=85 KEY_KP_MINUS=86 KEY_KP_PLUS=87 KEY_KP_ENTER=88
KEY_KP_1..KEY_KP_0 = 89..98 KEY_KP_PERIOD=99
KEY_NONUSBACKSLASH=100 KEY_APPLICATION=101
KEY_LCTRL=224 KEY_LSHIFT=225 KEY_LALT=226 KEY_LGUI=227
KEY_RCTRL=228 KEY_RSHIFT=229 KEY_RALT=230 KEY_RGUI=231
```
(Son los SDL2 scancodes.)
### Matemáticas
`abs(x)`, `ceil(x)`, `flr(x)`, `sgn(x)`, `sin(x)`, `cos(x)`, `atan2(dx, dy)`, `sqrt(x)`, `max(a,b)`, `min(a,b)`, `mid(a,b,c)` (devuelve el del medio, equivalente a `clamp`).
`rnd(n)` devuelve un entero en `[0, n-1]` (`rand()%n`). `srand(seed)` siembra el RNG.
### Strings
| Función | Descripción |
|---------|-------------|
| `tostr(v)` | Convierte valor a string. Soporta nil, function, table (formato `{k=v,...}`), number, boolean, string. |
| `strlen(s)` | Longitud en bytes. |
| `ascii(s, i)` | Código del byte en índice `i` (0-based). |
| `chr(n)` | String de un solo carácter cuyo código es `n`. |
| `substr(s, start, length)` | Subcadena. |
> Nota: Lua estándar también está disponible, así que `string.format`, `string.sub`, etc., funcionan. Pero los demos usan estas helpers.
### Memoria
| Función | Descripción |
|---------|-------------|
| `peek(addr)` | Lee 1 byte de la VRAM/memoria (0..0x1FFF). |
| `poke(addr, val)` | Escribe 1 byte. |
| `memcpy(dst, src, size)` | Copia bytes en la memoria del fantasy console. |
| `setchar(idx, b0..b7)` | Define los 8 bytes del carácter `idx` en el char-ROM (sobrescribe la fuente). |
**Mapa de memoria** (8 KB total, `mem[8192]`):
- `0x0000` (0): char_screen (matriz de códigos de carácter por celda)
- Tras char_screen viene color_screen (offset = `screen_width * screen_height`)
- `0x0A00` (2560 = `MEM_CHAR_OFFSET`): char-ROM (definición de glifos, 8 bytes por carácter, 256 chars = 2048 bytes)
- `0x1200` (4608 = `MEM_BOOT_OFFSET`): zona de boot/recursos de ROM
Para los modos 1 y 2 los color_screen offsets son 1200 y 300 respectivamente; en modo 3 es 768; en modo 0 no hay color_screen por celda (color global).
### Audio
**Sonido simple:**
- `sound(freq, len)` — onda cuadrada a `freq` Hz durante `len` (en algo similar a centésimas de segundo; `audio_len = len*44.1`).
- `nosound()` — silencio inmediato.
**Mini-lenguaje MML — `play(str)`:**
Sintaxis tipo BASIC `PLAY` / MML. Tokens (case-sensitive, minúsculas):
| Token | Significado |
|-------|-------------|
| `c d e f g a b` | Nota. Acepta sufijo `#` o `+` (sostenido) o `-` (bemol). Luego dígito 0-9 para duración. |
| `r` | Silencio. Acepta dígito de duración. |
| `o<0-7>` | Octava absoluta. |
| `>` `<` | Sube / baja octava. |
| `l<0-9>` | Longitud por defecto para notas sin duración. |
| `v<0-9>` | Volumen (se traduce a `(d-0)<<4`). |
| `t<0-9>` | Tempo. |
Duraciones: índice 0-9 → tabla `{313,625,938,1250,1875,2500,3750,5000,7500,10000}` (de "redonda" a "trentaidosava", aproximadamente).
Ejemplo (de `breakout.lua`):
```lua
play("l0o3bagfedc") -- escala descendente como sonido de game-over
play("o5l0c") -- pitido agudo (rebote)
```
### Ficheros y portapapeles
| Función | Descripción |
|---------|-------------|
| `load([filename])` | Reinicia y carga otro `.lua` (o el mismo si filename=nil). |
| `fileout(name, addr, size)` | Vuelca `size` bytes de memoria a un binario. |
| `filein(name, addr, size)` | Carga un binario a memoria. |
| `toclipboard(str)` | Copia al portapapeles del SO. |
| `fromclipboard()` | Lee del portapapeles (máx 1023 chars). |
### Utilidades de tiempo / frame
| Función | Descripción |
|---------|-------------|
| `time()` | Milisegundos desde inicio (`SDL_GetTicks()`). |
| `cnt()` | Contador de frames desde el último `rst()`. |
| `rst()` | Resetea el contador de frames a 0. |
| `log(str)` | Imprime en la consola de debug (no en pantalla). |
---
## 5. Caracteres especiales útiles
Los demos usan códigos > 127 que corresponden a glifos definidos en `rom.c` (el char-ROM por defecto). Algunos vistos:
- `\003` (3) — un bloque relleno (usado en pong para los compases)
- `\016` (16) — cubo de caja (en sokoban)
- `\127` (127) — pared en sokoban (redefinido con `setchar(127, ...)`)
- `\143`, `\154`, `\150`, `\156`, `\149` — esquinas y trazos de marcos
- `\248`, `\250`, `\251` — sprite animado de "OK" en sokoban
- `\233` — pelota en breakout
- `\131` — pala en breakout
- `\001` — cubo de tetromino (redefinido con `setchar(1, 0xff,0x81,...)`)
Para usarlos siempre se puede hacer `setchar(idx, b0..b7)` con la bitmap deseada y luego imprimirlo con `print(chr(idx), x, y)`.
---
## 6. Patrón típico de un juego
```lua
function init()
mode(1)
cls()
-- estado inicial
player = {x=10, y=15}
score = 0
end
function update()
-- input
if btnp(KEY_LEFT) then player.x = player.x - 1 end
if btnp(KEY_RIGHT) then player.x = player.x + 1 end
-- lógica
-- ...
-- render (no hay vsync explícito; el bucle ya hace flip al final)
cls()
color(COLOR_WHITE, COLOR_BLACK)
print("\248", player.x, player.y)
print("SCORE: "..tostr(score), 0, 0)
end
```
**Cosas a recordar:**
- No se "pintan" píxeles; se imprime un código de carácter en una celda y se le asocia un atributo de color (ink + paper). Para gráficos personalizados, redefinir glifos con `setchar`.
- El bucle de render lo hace el motor C++ después de `update()` — no hay que llamar a ningún `flip`.
- El `state machine` típico se hace asignando `update = otra_funcion` (ver `demos/sokoban.lua`).
- Las coordenadas de pantalla son **enteras y por celda**, no por píxel. (0,0) es esquina superior izquierda.
- Para depurar: `log("mensaje")` o pulsar ESC y usar la consola con `?variable`.
---
## 7. Cómo compilar el intérprete
Desde `c:/mingw/gitea/ascii/`:
```sh
make windows
```
Requiere MinGW (g++) y SDL2 para Windows. Produce `ascii.exe`. Para correr Pepe Runner:
```sh
ascii.exe pepe_runner.lua
```
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+58
View File
@@ -0,0 +1,58 @@
uses crt;
const
num_map = 6;
var
fich_o1, fich_d : file of byte;
buffer : byte;
j : integer;
i : longint;
nom : string;
begin
clrscr;
asm { hide cursor }
mov ax,0100h
mov cx,0100h
int 10h
end;
Write('UNINT MAPES ... ');
Assign(fich_d,'total.map');
Rewrite(fich_d);
for j:=0 to num_map do
begin
GotoXY(17,1);
Write((j*100) div num_map:3, '%');
str(j,nom);
nom := nom + '.map';
Assign(fich_o1, nom);
Reset(fich_o1);
for i:=1 to FileSize(fich_o1) do
begin
Read(fich_o1,buffer);
Write(fich_d,buffer);
end;
close(fich_o1);
end;
close(fich_d);
GotoXY(1,3);
Writeln('COMPLET.');
Writeln('(Pulsa una tecla per acabar)');
Readkey;
end.
Binary file not shown.
+58
View File
@@ -0,0 +1,58 @@
uses crt;
const
num_map = 10;
var
fich_o1, fich_d : file of byte;
buffer : byte;
j : integer;
i : longint;
nom : string;
begin
clrscr;
asm { hide cursor }
mov ax,0100h
mov cx,0100h
int 10h
end;
Write('UNINT MAPES ... ');
Assign(fich_d,'total.map');
Rewrite(fich_d);
for j:=0 to num_map do
begin
GotoXY(17,1);
Write((j*100) div num_map:3, '%');
str(j,nom);
nom := nom + '.map';
Assign(fich_o1, nom);
Reset(fich_o1);
for i:=1 to FileSize(fich_o1) do
begin
Read(fich_o1,buffer);
Write(fich_d,buffer);
end;
close(fich_o1);
end;
close(fich_d);
GotoXY(1,3);
Writeln('COMPLET.');
Writeln('(Pulsa una tecla per acabar)');
Readkey;
end.
Binary file not shown.
Binary file not shown.
+776
View File
@@ -0,0 +1,776 @@
uses grafix, jinput, utext, tipos, crt;
procedure FaseNova;forward;
{##############################################################}
{# O F F S E T M A P A #}
{##############################################################}
function OffsetMapa:longint;
var i:longint;
fich : file of byte;
buffer : byte;
marca : integer;
begin
i := 0;
Assign(fich, 'runner.exe');
Reset(fich);
marca := 0;
repeat
Read(fich, buffer);
inc(i);
if buffer = ord('*') then
inc(marca)
else
marca := 0;
until (marca = 10);
OffsetMapa := i;
end;
{##############################################################}
{# C A R R E G A R E C O R D S #}
{##############################################################}
procedure CarregaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
Seek(fich, FileSize(fich)-6);
Read(fich, buffer); { centenes }
hi_score := buffer * 100;
Read(fich, buffer); { decenes }
hi_score := hi_score + (buffer * 10);
Read(fich, buffer); { unitats }
hi_score := hi_score + buffer;
Read(fich, buffer); { 1¦ lletra }
nom_hi_score := chr(buffer+45);
Read(fich, buffer); { 2¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer+45);
Read(fich, buffer); { 3¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer+45);
Close(fich);
end;
{##############################################################}
{# G U A R D A R E C O R D S #}
{##############################################################}
procedure GuardaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
Seek(fich, FileSize(fich)-6);
buffer := score div 100;
Write(fich, buffer); { centenes }
buffer := (score - (buffer*100)) div 10;
Write(fich, buffer); { decenes }
buffer := (score - (buffer*10));
Write(fich, buffer); { unitats }
buffer := ord(nom_hi_score[1])-45;
Write(fich, buffer); { 1¦ lletra }
buffer := ord(nom_hi_score[2])-45;
Write(fich, buffer); { 2¦ lletra }
buffer := ord(nom_hi_score[3])-45;
Write(fich, buffer); { 3¦ lletra }
Close(fich);
end;
{##############################################################}
{# T R A G A P A N T A L L A #}
{##############################################################}
procedure TragaPantalla;
begin
for k:=0 to 23 do
begin
{ despla‡a cap avall }
for i:=0 to 39 do
for j:=23 downto 1 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j-1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j-1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(13,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
end;
end;
{##############################################################}
{# P O S A R N O M #}
{##############################################################}
procedure PosarNom;
var index : integer;
Key : byte;
Tecla : Pchar;
begin
nom_hi_score := '...';
index := 1;
PutStringCENTERED(13, 15, 'Enhorabona, has');
PutStringCENTERED(14, 15, 'aconseguit un nou record');
PutStringCENTERED(16, 15, nom_hi_score);
repeat
if QTeclaPuls then
begin
Key := AgarrarTecla;
Tecla := nomTECLES[Key];
nom_hi_score[index] := Tecla^;
inc(index);
PutStringCENTERED(16, 15, nom_hi_score);
repeat until not(QTeclaPuls);
end;
until (index = 4);
GuardaRecords;
end;
{##############################################################}
{# G A M E O V E R #}
{##############################################################}
procedure GameOver;
begin
pepe.vides := 0;
TragaPantalla;
cls($B800);
PutStringCENTERED(10, 15, 'G A M E O V E R');
for i:=0 to 100 do espera_VGA;
if score > hi_score then PosarNom;
GetPaleta(paleta);
FadeDown(0,0,0,0);
cls($B800);
SetPaleta(paleta);
end;
{##############################################################}
{# F I N A L P A N T A L L A #}
{##############################################################}
procedure FinalPantalla;
begin
TragaPantalla;
FaseNova;
end;
{##############################################################}
{# M O R T #}
{##############################################################}
procedure Mort;
begin
dec(pepe.vides);
pepe.posX := 19;
pepe.posY := 23;
end;
{##############################################################}
{# M O R T M A L O #}
{##############################################################}
procedure MortMalo(num: byte);
begin
malo[num].posX := 39;
malo[num].posY := 1;
malo[num].color := 3;
malo[num].estat := caent;
malo[num].IAclock := 0;
mapa[malo[num].carrega.posX, malo[num].carrega.posY].tipo := diners;
malo[num].carrega.OK := false;
malo[num].carrega.posX := 0;
malo[num].carrega.posY := 0;
end;
{##############################################################}
{# F O R A D A R #}
{##############################################################}
procedure Foradar(posX, posY : word);
begin
{ mapa[posX, posY].tipo := buit;}
mapa[posX, posY].temps := bloc_out;
end;
{##############################################################}
{# M O U P E P E #}
{##############################################################}
procedure MouPepe;
var hi_ha_malo_baix : boolean;
begin
if TeclaPuls(KeyQ) then
begin
if mapa[pepe.posX, pepe.posY].tipo=escala then
begin
dec(pepe.posY);
end;
end
else
if TeclaPuls(KeyA) then
begin
if (mapa[pepe.posX, pepe.posY+1].tipo=escala) or (mapa[pepe.posX, pepe.posY+1].tipo=buit) then
inc(pepe.posY);
end;
if TeclaPuls(KeyO) then
begin
if (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
dec(pepe.posX);
end
else
if TeclaPuls(KeyP) then
begin
if (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
inc(pepe.posX);
end
else
if TeclaPuls(KeySPACE) then
begin
if (mapa[pepe.posX-1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX-1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX-1, pepe.posY+1);
end
else
if TeclaPuls(KeyM) then
begin
if (mapa[pepe.posX+1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX+1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX+1, pepe.posY+1);
end;
if TeclaPuls(KeyH) then
begin
repeat until not(TeclaPuls(KeyH));
repeat until TeclaPuls(KeyH);
repeat until not(TeclaPuls(KeyH));
end;
{ si no passa res... }
pepe.estat := normal;
{ final pantalla }
if pepe.posY = 1 then FinalPantalla;
{ emparedat }
if mapa[pepe.posX, pepe.posY].tipo = pedra then
Mort;
{ agarra diners }
if mapa[pepe.posX, pepe.posY].tipo = diners then
begin
mapa[pepe.posX, pepe.posY].tipo := buit;
inc(score);
dec(diners_pantalla);
end;
{ bordes X pantalla }
if pepe.posX<0 then pepe.posX:=0;
if pepe.posX>39 then pepe.posX:=39;
{ gravetat }
if ((mapa[pepe.posX, pepe.posY+1].tipo<>escala) and (mapa[pepe.posX, pepe.posY+1].tipo<>pedra))
and ((mapa[pepe.posX, pepe.posY].tipo=buit) or (mapa[pepe.posX, pepe.posY].tipo=diners)) then
begin
hi_ha_malo_baix := FALSE;
for i:=0 to num_malos-1 do
if (pepe.posX = malo[i].posX) and (pepe.posY+1 = malo[i].posY) then
hi_ha_malo_baix := TRUE;
if not(hi_ha_malo_baix) then
begin
inc(pepe.posY);
pepe.estat := caent;
end;
end;
{ bordes Y pantalla }
if pepe.posY<0 then pepe.posY:=0;
if pepe.posY>24 then pepe.posY:=24;
end;
{##############################################################}
{# S E L E C T E S T A T #}
{##############################################################}
function SelectEstat(num: byte):byte;
var nou_estat : byte;
Sestat:byte;
x:byte;
estat_pX,estat_pY:byte;
buscar:byte;
begin
nou_estat := 0;
Sestat:=0;
if mapa[malo[num].posX+1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+dreta;
if mapa[malo[num].posX-1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+esquerra;
if mapa[malo[num].posX, malo[num].posY].tipo = escala then
nou_estat := nou_estat + pujar;
if mapa[malo[num].posX, malo[num].posY+1].tipo = escala then
nou_estat := nou_estat + baixar;
if nou_estat=0 then Sestat:=10; {no pot moure's}
if malo[num].posX>pepe.posX then estat_pX:=esquerra
else estat_pX:=dreta;
if malo[num].posY>pepe.posY then estat_pY:=pujar
else estat_pY:=baixar;
x:=random(4);
buscar:=random(100);
if (buscar<50) and ((nou_estat and estat_PX=estat_PX) or
(nou_estat and estat_PY=estat_PY)) then
begin
if (nou_estat and estat_PX=estat_PX) then Sestat:=estat_PX
else Sestat:=estat_PY;
end
else
repeat
case x of
0:if nou_estat and dreta =dreta then Sestat:=dreta;
1:if nou_estat and esquerra =esquerra then Sestat:=esquerra;
2:if nou_estat and pujar =pujar then Sestat:=pujar;
3:if nou_estat and baixar =baixar then Sestat:=baixar;
end;
inc(x);
x:=x and $03;
until Sestat<>0;
SelectEstat:=Sestat;
if (mapa[malo[num].posX, malo[num].posY+1].tipo <> pedra)
and (mapa[malo[num].posX, malo[num].posY+1].tipo <> escala) then
SelectEstat:=caent;
end;
{##############################################################}
{# A G A F A R E S C A L A #}
{##############################################################}
function AgafarEscala(num:byte):byte;
var x:byte;
ag:boolean;
estat:byte;
begin
estat:=malo[num].estat;
if (estat=dreta) or (estat=esquerra) then
begin
x:=random(100);
if x<80 then ag:=True else ag:=false;
if ag then
begin
if (mapa[malo[num].posX, malo[num].posY].tipo = escala) then
estat:=pujar
else
if (mapa[malo[num].posX, malo[num].posY+1].tipo = escala) then
estat:=baixar;
end;
end;
AgafarEscala:=estat;
end;
{##############################################################}
{# M O U M A L O S #}
{##############################################################}
procedure MouMalos;
begin
for i:=0 to num_malos-1 do
begin
if malo[i].IAclock = 0 then
malo[i].estat := SelectEstat(i);
malo[i].estat:=AgafarEscala(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo <> pedra) and
(mapa[malo[i].posX, malo[i].posY+1].tipo <> escala)) and
(mapa[malo[i].posX, malo[i].posY].tipo <> corda) then
malo[i].estat:=caent;
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) or
(mapa[malo[i].posX, malo[i].posY+1].tipo = escala)) and
(malo[i].estat=caent) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY].tipo = buit) and
(malo[i].estat=pujar)) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) and
(malo[i].estat=baixar)) then
malo[i].estat:=SelectEstat(i);
case malo[i].estat of
dreta : inc(malo[i].posX);
esquerra : dec(malo[i].posX);
pujar : dec(malo[i].posY);
baixar : inc(malo[i].posY);
caent : inc(malo[i].posY);
end;
{ bordes X }
if malo[i].posX<0 then
begin
malo[i].posX:=0;
malo[i].estat := dreta;
end;
if malo[i].posX>39 then
begin
malo[i].posX:=39;
malo[i].estat := esquerra;
end;
{ bordes Y }
if malo[i].posY<0 then
begin
malo[i].posY:=0;
end;
if malo[i].posY>24 then
begin
malo[i].posY:=24;
end;
{ agarrar diners }
if (mapa[malo[i].posX, malo[i].posY].tipo = diners)
and not(malo[i].carrega.OK) then
begin
mapa[malo[i].posX, malo[i].posY].tipo := buit;
malo[i].color := 11;
malo[i].carrega.OK := TRUE;
malo[i].carrega.posX := malo[i].posX;
malo[i].carrega.posY := malo[i].posY;
end;
{ emparedat }
if mapa[malo[i].posX, malo[i].posY].tipo = pedra then
MortMalo(i);
inc(malo[i].IAclock);
if malo[i].IAclock = temps_IA then malo[i].IAclock := 0;
end;
end;
{##############################################################}
{# C A R R E G A M A P A #}
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'runner.exe');
Reset(fich);
Seek(fich, (level * 1000)+offset_mapa);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo:=buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
{# C H E C K M O R T P E R M A L O S #}
{##############################################################}
procedure CheckMortPerMalos;
begin
for i:=0 to num_malos-1 do
if (malo[i].posX = pepe.posX) and (malo[i].posY = pepe.posY) then
Mort;
end;
{##############################################################}
{# C H E C K M A P A C O M P L E T #}
{##############################################################}
procedure CheckMapaComplet;
begin
if diners_pantalla = 0 then
for j:=1 to 23 do
begin
if mapa[0,j].tipo <> pedra then
begin
mapa[0,j].tipo := escala;
mapa[0,j].color := color_escala;
end
else
break;
end;
end;
{##############################################################}
{# C H E C K M A P A #}
{##############################################################}
procedure CheckMapa;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
case mapa[i,j].temps of
0 : begin
mapa[i,j].temps := -1;
mapa[i,j].tipo := pedra;
end;
1,bloc_out-1 : begin
mapa[i,j].tipo := bloc3;
dec(mapa[i,j].temps)
end;
2,bloc_out-2 : begin
mapa[i,j].tipo := bloc2;
dec(mapa[i,j].temps)
end;
3,bloc_out-3 : begin
mapa[i,j].tipo := bloc1;
dec(mapa[i,j].temps)
end;
4,bloc_out-4 : begin
mapa[i,j].tipo := buit;
dec(mapa[i,j].temps)
end;
-1 : ;
else dec(mapa[i,j].temps)
end;
end;
CheckMapaComplet;
end;
{##############################################################}
{# F A S E N O V A #}
{##############################################################}
procedure FaseNova;
begin
inc(level);
if level = (num_fases + 1) then
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# I N I C I A L I T Z A C I O #}
{##############################################################}
procedure Inicialitzacio;
begin
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
pepe.vides := 3;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# T I T O L #}
{##############################################################}
procedure Titol;
begin
getpaleta(paleta);
blackout;
PutStringCENTERED(10, 15, 'JAILDESIGNER');
PutStringCENTERED(12, 15, 'presenta');
FadeUp(paleta, 1);
for i:=0 to 100 do espera_VGA;
Fadedown(0,0,0,0);
level := 0;
CarregaMapa;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
move(mem[pant1:0], mem[$B800:0], 2000);
FadeUp(paleta, 0);
for i:=0 to 100 do espera_VGA;
for k:=0 to 2 do
begin
{ despla‡a cap amunt }
for i:=0 to 39 do
for j:=0 to 23 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j+1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j+1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
end;
end;
{##############################################################}
{# M E N U #}
{##############################################################}
procedure Menu;
var num : integer;
begin
num := 1;
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
repeat
repeat until QteclaPuls;
if (TeclaPuls(KeyArrowDown)) or (TeclaPuls(KeyA)) then
num := 2;
if (TeclaPuls(KeyArrowUp)) or (TeclaPuls(KeyQ)) then
num := 1;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
if num = 1 then
begin
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
end
else
begin
PutStringCENTERED(18, 15, 'COMEN€AR JOC');
PutStringWINDOWED(20, 14, 'EIXIR');
end;
until TeclaPuls(KeyENTER);
if num = 1 then
{ joc }
begin
Inicialitzacio;
CarregaRecords;
repeat
MouPepe;
CheckMortPerMalos;
if (Clock mod 4) = 0 then MouMalos;
CheckMortPerMalos;
PintaPantalla;
CheckMapa;
until TeclaPuls(KeyESC) or (Pepe.vides<0);
if TeclaPuls(keyESC) then
score := 0;
GameOver;
end;
if num = 2 then
{ menu d'opcions }
exit_game := TRUE;
end;
{##############################################################}
begin
instalarKB;
setmode(1);
HideCursor;
SetUpVirtual(ptrpant1, pant1);
randomize;
offset_mapa := OffsetMapa;
exit_game := FALSE;
Titol;
repeat
Menu;
until exit_game;
TancarVirtual(ptrpant1);
setmode(3);
desinstalarKB;
end.
Binary file not shown.
+776
View File
@@ -0,0 +1,776 @@
uses grafix, jinput, utext, tipos, crt;
procedure FaseNova;forward;
{##############################################################}
{# O F F S E T M A P A #}
{##############################################################}
function OffsetMapa:longint;
var i:longint;
fich : file of byte;
buffer : byte;
marca : integer;
begin
i := 0;
Assign(fich, 'runner.exe');
Reset(fich);
marca := 0;
repeat
Read(fich, buffer);
inc(i);
if buffer = ord('*') then
inc(marca)
else
marca := 0;
until (marca = 10);
OffsetMapa := i;
end;
{##############################################################}
{# C A R R E G A R E C O R D S #}
{##############################################################}
procedure CarregaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
Seek(fich, FileSize(fich)-6);
Read(fich, buffer); { centenes }
hi_score := buffer * 100;
Read(fich, buffer); { decenes }
hi_score := hi_score + (buffer * 10);
Read(fich, buffer); { unitats }
hi_score := hi_score + buffer;
Read(fich, buffer); { 1¦ lletra }
nom_hi_score := chr(buffer+45);
Read(fich, buffer); { 2¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer+45);
Read(fich, buffer); { 3¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer+45);
Close(fich);
end;
{##############################################################}
{# G U A R D A R E C O R D S #}
{##############################################################}
procedure GuardaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
Seek(fich, FileSize(fich)-6);
buffer := score div 100;
Write(fich, buffer); { centenes }
buffer := (score - (buffer*100)) div 10;
Write(fich, buffer); { decenes }
buffer := (score - (buffer*10));
Write(fich, buffer); { unitats }
buffer := ord(nom_hi_score[1])-45;
Write(fich, buffer); { 1¦ lletra }
buffer := ord(nom_hi_score[2])-45;
Write(fich, buffer); { 2¦ lletra }
buffer := ord(nom_hi_score[3])-45;
Write(fich, buffer); { 3¦ lletra }
Close(fich);
end;
{##############################################################}
{# T R A G A P A N T A L L A #}
{##############################################################}
procedure TragaPantalla;
begin
for k:=0 to 23 do
begin
{ despla‡a cap avall }
for i:=0 to 39 do
for j:=23 downto 1 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j-1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j-1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(13,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
end;
end;
{##############################################################}
{# P O S A R N O M #}
{##############################################################}
procedure PosarNom;
var index : integer;
Key : byte;
Tecla : Pchar;
begin
nom_hi_score := '...';
index := 1;
PutStringCENTERED(13, 15, 'Enhorabona, has');
PutStringCENTERED(14, 15, 'aconseguit un nou record');
PutStringCENTERED(16, 15, nom_hi_score);
repeat
if QTeclaPuls then
begin
Key := AgarrarTecla;
Tecla := nomTECLES[Key];
nom_hi_score[index] := Tecla^;
inc(index);
PutStringCENTERED(16, 15, nom_hi_score);
repeat until not(QTeclaPuls);
end;
until (index = 4);
GuardaRecords;
end;
{##############################################################}
{# G A M E O V E R #}
{##############################################################}
procedure GameOver;
begin
pepe.vides := 0;
TragaPantalla;
cls($B800);
PutStringCENTERED(10, 15, 'G A M E O V E R');
for i:=0 to 100 do espera_VGA;
if score > hi_score then PosarNom;
GetPaleta(paleta);
FadeDown(0,0,0,0);
cls($B800);
SetPaleta(paleta);
end;
{##############################################################}
{# F I N A L P A N T A L L A #}
{##############################################################}
procedure FinalPantalla;
begin
TragaPantalla;
FaseNova;
end;
{##############################################################}
{# M O R T #}
{##############################################################}
procedure Mort;
begin
dec(pepe.vides);
pepe.posX := 19;
pepe.posY := 23;
end;
{##############################################################}
{# M O R T M A L O #}
{##############################################################}
procedure MortMalo(num: byte);
begin
malo[num].posX := 39;
malo[num].posY := 1;
malo[num].color := 3;
malo[num].estat := caent;
malo[num].IAclock := 0;
mapa[malo[num].carrega.posX, malo[num].carrega.posY].tipo := diners;
malo[num].carrega.OK := false;
malo[num].carrega.posX := 0;
malo[num].carrega.posY := 0;
end;
{##############################################################}
{# F O R A D A R #}
{##############################################################}
procedure Foradar(posX, posY : word);
begin
{ mapa[posX, posY].tipo := buit;}
mapa[posX, posY].temps := bloc_out;
end;
{##############################################################}
{# M O U P E P E #}
{##############################################################}
procedure MouPepe;
var hi_ha_malo_baix : boolean;
begin
if TeclaPuls(KeyQ) then
begin
if mapa[pepe.posX, pepe.posY].tipo=escala then
begin
dec(pepe.posY);
end;
end
else
if TeclaPuls(KeyA) then
begin
if (mapa[pepe.posX, pepe.posY+1].tipo=escala) or (mapa[pepe.posX, pepe.posY+1].tipo=buit) then
inc(pepe.posY);
end;
if TeclaPuls(KeyO) then
begin
if (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
dec(pepe.posX);
end
else
if TeclaPuls(KeyP) then
begin
if (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
inc(pepe.posX);
end
else
if TeclaPuls(KeySPACE) then
begin
if (mapa[pepe.posX-1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX-1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX-1, pepe.posY+1);
end
else
if TeclaPuls(KeyM) then
begin
if (mapa[pepe.posX+1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX+1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX+1, pepe.posY+1);
end;
if TeclaPuls(KeyH) then
begin
repeat until not(TeclaPuls(KeyH));
repeat until TeclaPuls(KeyH);
repeat until not(TeclaPuls(KeyH));
end;
{ si no passa res... }
pepe.estat := normal;
{ final pantalla }
if pepe.posY = 1 then FinalPantalla;
{ emparedat }
if mapa[pepe.posX, pepe.posY].tipo = pedra then
Mort;
{ agarra diners }
if mapa[pepe.posX, pepe.posY].tipo = diners then
begin
mapa[pepe.posX, pepe.posY].tipo := buit;
inc(score);
dec(diners_pantalla);
end;
{ bordes X pantalla }
if pepe.posX<0 then pepe.posX:=0;
if pepe.posX>39 then pepe.posX:=39;
{ gravetat }
if ((mapa[pepe.posX, pepe.posY+1].tipo<>escala) and (mapa[pepe.posX, pepe.posY+1].tipo<>pedra))
and ((mapa[pepe.posX, pepe.posY].tipo=buit) or (mapa[pepe.posX, pepe.posY].tipo=diners)) then
begin
hi_ha_malo_baix := FALSE;
for i:=0 to num_malos-1 do
if (pepe.posX = malo[i].posX) and (pepe.posY+1 = malo[i].posY) then
hi_ha_malo_baix := TRUE;
if not(hi_ha_malo_baix) then
begin
inc(pepe.posY);
pepe.estat := caent;
end;
end;
{ bordes Y pantalla }
if pepe.posY<0 then pepe.posY:=0;
if pepe.posY>24 then pepe.posY:=24;
end;
{##############################################################}
{# S E L E C T E S T A T #}
{##############################################################}
function SelectEstat(num: byte):byte;
var nou_estat : byte;
Sestat:byte;
x:byte;
estat_pX,estat_pY:byte;
buscar:byte;
begin
nou_estat := 0;
Sestat:=0;
if mapa[malo[num].posX+1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+dreta;
if mapa[malo[num].posX-1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+esquerra;
if mapa[malo[num].posX, malo[num].posY].tipo = escala then
nou_estat := nou_estat + pujar;
if mapa[malo[num].posX, malo[num].posY+1].tipo = escala then
nou_estat := nou_estat + baixar;
if nou_estat=0 then Sestat:=10; {no pot moure's}
if malo[num].posX>pepe.posX then estat_pX:=esquerra
else estat_pX:=dreta;
if malo[num].posY>pepe.posY then estat_pY:=pujar
else estat_pY:=baixar;
x:=random(4);
buscar:=random(100);
if (buscar<50) and ((nou_estat and estat_PX=estat_PX) or
(nou_estat and estat_PY=estat_PY)) then
begin
if (nou_estat and estat_PX=estat_PX) then Sestat:=estat_PX
else Sestat:=estat_PY;
end
else
repeat
case x of
0:if nou_estat and dreta =dreta then Sestat:=dreta;
1:if nou_estat and esquerra =esquerra then Sestat:=esquerra;
2:if nou_estat and pujar =pujar then Sestat:=pujar;
3:if nou_estat and baixar =baixar then Sestat:=baixar;
end;
inc(x);
x:=x and $03;
until Sestat<>0;
SelectEstat:=Sestat;
if (mapa[malo[num].posX, malo[num].posY+1].tipo <> pedra)
and (mapa[malo[num].posX, malo[num].posY+1].tipo <> escala) then
SelectEstat:=caent;
end;
{##############################################################}
{# A G A F A R E S C A L A #}
{##############################################################}
function AgafarEscala(num:byte):byte;
var x:byte;
ag:boolean;
estat:byte;
begin
estat:=malo[num].estat;
if (estat=dreta) or (estat=esquerra) then
begin
x:=random(100);
if x<80 then ag:=True else ag:=false;
if ag then
begin
if (mapa[malo[num].posX, malo[num].posY].tipo = escala) then
estat:=pujar
else
if (mapa[malo[num].posX, malo[num].posY+1].tipo = escala) then
estat:=baixar;
end;
end;
AgafarEscala:=estat;
end;
{##############################################################}
{# M O U M A L O S #}
{##############################################################}
procedure MouMalos;
begin
for i:=0 to num_malos-1 do
begin
if malo[i].IAclock = 0 then
malo[i].estat := SelectEstat(i);
malo[i].estat:=AgafarEscala(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo <> pedra) and
(mapa[malo[i].posX, malo[i].posY+1].tipo <> escala)) and
(mapa[malo[i].posX, malo[i].posY].tipo <> corda) then
malo[i].estat:=caent;
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) or
(mapa[malo[i].posX, malo[i].posY+1].tipo = escala)) and
(malo[i].estat=caent) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY].tipo = buit) and
(malo[i].estat=pujar)) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) and
(malo[i].estat=baixar)) then
malo[i].estat:=SelectEstat(i);
case malo[i].estat of
dreta : inc(malo[i].posX);
esquerra : dec(malo[i].posX);
pujar : dec(malo[i].posY);
baixar : inc(malo[i].posY);
caent : inc(malo[i].posY);
end;
{ bordes X }
if malo[i].posX<0 then
begin
malo[i].posX:=0;
malo[i].estat := dreta;
end;
if malo[i].posX>39 then
begin
malo[i].posX:=39;
malo[i].estat := esquerra;
end;
{ bordes Y }
if malo[i].posY<0 then
begin
malo[i].posY:=0;
end;
if malo[i].posY>24 then
begin
malo[i].posY:=24;
end;
{ agarrar diners }
if (mapa[malo[i].posX, malo[i].posY].tipo = diners)
and not(malo[i].carrega.OK) then
begin
mapa[malo[i].posX, malo[i].posY].tipo := buit;
malo[i].color := 11;
malo[i].carrega.OK := TRUE;
malo[i].carrega.posX := malo[i].posX;
malo[i].carrega.posY := malo[i].posY;
end;
{ emparedat }
if mapa[malo[i].posX, malo[i].posY].tipo = pedra then
MortMalo(i);
inc(malo[i].IAclock);
if malo[i].IAclock = temps_IA then malo[i].IAclock := 0;
end;
end;
{##############################################################}
{# C A R R E G A M A P A #}
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'runner.exe');
Reset(fich);
Seek(fich, (level * 1000)+offset_mapa);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo:=buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
{# C H E C K M O R T P E R M A L O S #}
{##############################################################}
procedure CheckMortPerMalos;
begin
for i:=0 to num_malos-1 do
if (malo[i].posX = pepe.posX) and (malo[i].posY = pepe.posY) then
Mort;
end;
{##############################################################}
{# C H E C K M A P A C O M P L E T #}
{##############################################################}
procedure CheckMapaComplet;
begin
if diners_pantalla = 0 then
for j:=1 to 23 do
begin
if mapa[0,j].tipo <> pedra then
begin
mapa[0,j].tipo := escala;
mapa[0,j].color := color_escala;
end
else
break;
end;
end;
{##############################################################}
{# C H E C K M A P A #}
{##############################################################}
procedure CheckMapa;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
case mapa[i,j].temps of
0 : begin
mapa[i,j].temps := -1;
mapa[i,j].tipo := pedra;
end;
1,bloc_out-1 : begin
mapa[i,j].tipo := bloc3;
dec(mapa[i,j].temps)
end;
2,bloc_out-2 : begin
mapa[i,j].tipo := bloc2;
dec(mapa[i,j].temps)
end;
3,bloc_out-3 : begin
mapa[i,j].tipo := bloc1;
dec(mapa[i,j].temps)
end;
4,bloc_out-4 : begin
mapa[i,j].tipo := buit;
dec(mapa[i,j].temps)
end;
-1 : ;
else dec(mapa[i,j].temps)
end;
end;
CheckMapaComplet;
end;
{##############################################################}
{# F A S E N O V A #}
{##############################################################}
procedure FaseNova;
begin
inc(level);
if level = (num_fases + 1) then
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# I N I C I A L I T Z A C I O #}
{##############################################################}
procedure Inicialitzacio;
begin
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
pepe.vides := 3;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# T I T O L #}
{##############################################################}
procedure Titol;
begin
getpaleta(paleta);
blackout;
PutStringCENTERED(10, 15, 'JAILDESIGNER');
PutStringCENTERED(12, 15, 'presenta');
FadeUp(paleta, 1);
for i:=0 to 100 do espera_VGA;
Fadedown(0,0,0,0);
level := 0;
CarregaMapa;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
move(mem[pant1:0], mem[$B800:0], 2000);
FadeUp(paleta, 0);
for i:=0 to 100 do espera_VGA;
for k:=0 to 2 do
begin
{ despla‡a cap amunt }
for i:=0 to 39 do
for j:=0 to 23 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j+1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j+1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
end;
end;
{##############################################################}
{# M E N U #}
{##############################################################}
procedure Menu;
var num : integer;
begin
num := 1;
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
repeat
repeat until QteclaPuls;
if (TeclaPuls(KeyArrowDown)) or (TeclaPuls(KeyA)) then
num := 2;
if (TeclaPuls(KeyArrowUp)) or (TeclaPuls(KeyQ)) then
num := 1;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
if num = 1 then
begin
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
end
else
begin
PutStringCENTERED(18, 15, 'COMEN€AR JOC');
PutStringWINDOWED(20, 14, 'EIXIR');
end;
until TeclaPuls(KeyENTER);
if num = 1 then
{ joc }
begin
Inicialitzacio;
CarregaRecords;
repeat
MouPepe;
CheckMortPerMalos;
if (Clock mod 4) = 0 then MouMalos;
CheckMortPerMalos;
PintaPantalla;
CheckMapa;
until TeclaPuls(KeyESC) or (Pepe.vides<0);
if TeclaPuls(keyESC) then
score := 0;
GameOver;
end;
if num = 2 then
{ menu d'opcions }
exit_game := TRUE;
end;
{##############################################################}
begin
instalarKB;
setmode(1);
HideCursor;
SetUpVirtual(ptrpant1, pant1);
randomize;
offset_mapa := OffsetMapa;
exit_game := FALSE;
repeat
Titol;
Menu;
until exit_game;
TancarVirtual(ptrpant1);
setmode(3);
desinstalarKB;
end.
Binary file not shown.
+17
View File
@@ -0,0 +1,17 @@
procedure HideCursor;assembler;
asm
mov ax,0100h
mov cx,0100h
int 10h
end;
procedure ShowCursor;assembler;
asm
mov ax,0100h
mov cx,0607h
int 10h
end;
begin
HideCursor;
end.
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
procedure HideCursor;assembler;
asm
mov ax,0100h
mov cx,0100h
int 10h
end;
procedure ShowCursor;assembler;
asm
mov ax,0100h
mov cx,0607h
int 10h
end;
begin
HideCursor;
ShowCursor;
end.
+99
View File
@@ -0,0 +1,99 @@
uses jinput, grafix, crt, tipos;
var
item : byte;
num_fase : string;
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'03.map');
Reset(fich);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo := buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
procedure PintaPantalla;
var i,j : word;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
mem[pant1:((GetmouseX) div 8)+(((GetmouseY) div 8)*80)]:=88;
mem[pant1:((GetmouseX) div 8)+(((GetmouseY) div 8)*80)+1]:=7;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1);
Write('X: ',(GetmouseX) div 16:2, ' Y: ', (GetmouseY) div 8:2, ' ITEM: ', chr(llista_items[item]));
end;
{##############################################################}
procedure SalvaMapa(numero : string);
var nom : string;
fich : file of byte;
begin
nom := numero+'.map';
Assign(fich, nom);
Rewrite(fich);
for i:=0 to 39 do
for j:=0 to 24 do
Write(fich, mapa[i,j].tipo);
Close(fich);
end;
{##############################################################}
begin
setmode(1);
SetMousePos(320,100);
SetMouseZone(0,16,640-16,200-8);
SetMouseSensitivity(10,10);
SetMouseInterruptRate(0);
SetUpVirtual(ptrpant1, pant1);
item := 1;
for i:=0 to 39 do
for j:=0 to 24 do
mapa[i,j].tipo:=buit;
{CarregaMapa;}
repeat
PintaPantalla;
if (estatboto(MBLeft)<>0) then
begin
mapa[(GetmouseX) div 16, (GetmouseY) div 8].tipo := llista_items[item];
mapa[(GetmouseX) div 16, (GetmouseY) div 8].color := color_items[item];
end;
if (estatboto(MBRight)<>0) then
begin
item := (item+1) mod num_items;
repeat until (estatboto(MBRight)=0);
end;
until keypressed;
gotoXY(10,10);
write('NUMERO DE FASE? ');
read(num_fase);
SalvaMapa(num_fase);
TancarVirtual(ptrpant1);
setmode(3);
end.
Binary file not shown.
+99
View File
@@ -0,0 +1,99 @@
uses jinput, grafix, crt, tipos;
var
item : byte;
num_fase : string;
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'03.map');
Reset(fich);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo := buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
procedure PintaPantalla;
var i,j : word;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
mem[pant1:((GetmouseX) div 8)+(((GetmouseY) div 8)*80)]:=88;
mem[pant1:((GetmouseX) div 8)+(((GetmouseY) div 8)*80)+1]:=7;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1);
Write('X: ',(GetmouseX) div 16:2, ' Y: ', (GetmouseY) div 8:2, ' ITEM: ', chr(llista_items[item]));
end;
{##############################################################}
procedure SalvaMapa(numero : string);
var nom : string;
fich : file of byte;
begin
nom := numero+'.map';
Assign(fich, nom);
Rewrite(fich);
for i:=0 to 39 do
for j:=0 to 24 do
Write(fich, mapa[i,j].tipo);
Close(fich);
end;
{##############################################################}
begin
setmode(1);
SetMousePos(320,100);
SetMouseZone(0,16,640-16,200-8);
SetMouseSensitivity(10,10);
SetMouseInterruptRate(0);
SetUpVirtual(ptrpant1, pant1);
item := 1;
for i:=0 to 39 do
for j:=0 to 24 do
mapa[i,j].tipo:=buit;
{CarregaMapa;}
repeat
PintaPantalla;
if (estatboto(MBLeft)<>0) then
begin
mapa[(GetmouseX) div 16, (GetmouseY) div 8].tipo := llista_items[item];
mapa[(GetmouseX) div 16, (GetmouseY) div 8].color := color_items[item];
end;
if (estatboto(MBRight)<>0) then
begin
item := (item+1) mod num_items;
repeat until (estatboto(MBRight)=0);
end;
until keypressed;
gotoXY(10,10);
write('NUMERO DE FASE? ');
read(num_fase);
SalvaMapa(num_fase);
TancarVirtual(ptrpant1);
setmode(3);
end.
Binary file not shown.
+90
View File
@@ -0,0 +1,90 @@
uses crt;
const
num_map = 6;
var
fich_exe, fich_map, fich_rec, fich_d : file of byte;
buffer : byte;
j : integer;
i : longint;
nom : string;
total : longint;
etiqueta : string;
begin
ClrScr;
asm { hide cursor }
mov ax,0100h
mov cx,0100h
int 10h
end;
etiqueta := '*mapa*';
Assign(fich_exe,'codi.exe');
Writeln('CODI.EXE');
Assign(fich_map,'total.map');
Writeln('TOTAL.MAP');
Assign(fich_rec,'records');
Writeln('RECORDS');
Assign(fich_d,'runner.exe');
Reset(fich_exe);
Reset(fich_map);
Reset(fich_rec);
Rewrite(fich_d);
Writeln;
Writeln;
Writeln('Escribint...');
GotoXY(14,6);
Write('RUNNER.EXE');
total := FileSize(fich_exe);
for i:=1 to FileSize(fich_exe) do
begin
Read(fich_exe,buffer);
Write(fich_d,buffer);
GotoXY(20,1);
Write(((i*100) div total):3,'%');
end;
for i:=1 to length(etiqueta) do
begin
buffer := ord(etiqueta[i]);
Write(fich_d,buffer);
end;
total := FileSize(fich_map);
for i:=1 to FileSize(fich_map) do
begin
Read(fich_map,buffer);
Write(fich_d,buffer);
GotoXY(20,2);
Write(((i*100) div total):3,'%');
end;
total := FileSize(fich_rec);
for i:=1 to FileSize(fich_rec) do
begin
Read(fich_rec,buffer);
Write(fich_d,buffer);
GotoXY(20,3);
Write(((i*100) div total):3,'%');
end;
close(fich_exe);
close(fich_map);
close(fich_rec);
close(fich_d);
GotoXY(1,6);
Writeln('Complet. ');
GotoXY(14,6);
Writeln('RUNNER.EXE');
Writeln;
Writeln('Pulsa una tecla per a eixir');
ReadKey;
end.
Binary file not shown.
+90
View File
@@ -0,0 +1,90 @@
uses crt;
const
num_map = 6;
var
fich_exe, fich_map, fich_rec, fich_d : file of byte;
buffer : byte;
j : integer;
i : longint;
nom : string;
total : longint;
etiqueta : string;
begin
ClrScr;
asm { hide cursor }
mov ax,0100h
mov cx,0100h
int 10h
end;
etiqueta := '*mapa*';
Assign(fich_exe,'codi.exe');
Writeln('CODI.EXE');
Assign(fich_map,'total.map');
Writeln('TOTAL.MAP');
Assign(fich_rec,'records');
Writeln('RECORDS');
Assign(fich_d,'runner.exe');
Reset(fich_exe);
Reset(fich_map);
Reset(fich_rec);
Rewrite(fich_d);
Writeln;
Writeln;
Writeln('Escribint...');
GotoXY(14,6);
Write('RUNNER.EXE');
total := FileSize(fich_exe);
for i:=1 to FileSize(fich_exe) do
begin
Read(fich_exe,buffer);
Write(fich_d,buffer);
GotoXY(20,1);
Write(((i*100) div total):3,'%');
end;
for i:=1 to 10 do
begin
buffer := ord('*');
Write(fich_d,buffer);
end;
total := FileSize(fich_map);
for i:=1 to FileSize(fich_map) do
begin
Read(fich_map,buffer);
Write(fich_d,buffer);
GotoXY(20,2);
Write(((i*100) div total):3,'%');
end;
total := FileSize(fich_rec);
for i:=1 to FileSize(fich_rec) do
begin
Read(fich_rec,buffer);
Write(fich_d,buffer);
GotoXY(20,3);
Write(((i*100) div total):3,'%');
end;
close(fich_exe);
close(fich_map);
close(fich_rec);
close(fich_d);
GotoXY(1,6);
Writeln('Complet. ');
GotoXY(14,6);
Writeln('RUNNER.EXE');
Writeln;
Writeln('Pulsa una tecla per a eixir');
ReadKey;
end.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+156
View File
@@ -0,0 +1,156 @@
unit input;
interface
uses jinput;
const
T_UP = KeyQ;
T_DOWN = KeyA;
T_LEFT = KeyO;
T_RIGHT = KeyP;
T_OK = KeySPACE;
T_NOK = KeyM;
retard_tecla = 10; { per a controlar les pulsacions de tecles }
var
tecla : word; { per a controlar les pulsacions de tecles }
J_OK : boolean; { indica la disponibilitat del Gamepad }
procedure Check_Joystick;
{ Funcio: Coloca en la variable global J_OK si esta el gamepad conectat }
function i_amunt:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
function i_avall:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
function i_esquerra:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
function i_dreta:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
function i_ok:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
function i_nok:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
function i_esc:boolean;
{ Funcio: mira si hem pulsat ESC }
implementation
{############################################################################
##### C H E C K J O Y S T I C K #####
############################################################################}
procedure Check_Joystick;
{ Funcio: Coloca en la variable global J_OK si esta el gamepad conectat }
begin
if (joyavaliable(joystick1)) then J_OK := TRUE else J_OK := FALSE;
end;
{############################################################################
##### A M U N T #####
############################################################################}
function i_amunt:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
begin
i_amunt := FALSE;
if tecla=0 then
if ((J_OK) and (joystick(joystick1_Y)=joy1_MIN_Y))
or (TeclaPuls(T_UP)) then
begin
i_amunt := TRUE;
tecla := retard_tecla;
end;
end;
{############################################################################
##### A V A L L #####
############################################################################}
function i_avall:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
begin
i_avall := FALSE;
if tecla=0 then
if ((J_OK) and (joystick(joystick1_Y)=joy1_MAX_Y))
or (TeclaPuls(T_DOWN)) then
begin
i_avall := TRUE;
tecla := retard_tecla;
end;
end;
{############################################################################
##### D R E T A #####
############################################################################}
function i_dreta:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
begin
i_dreta := FALSE;
if tecla=0 then
if ((J_OK) and (joystick(joystick1_X)=joy1_MAX_X))
or (TeclaPuls(T_RIGHT)) then
begin
i_dreta := TRUE;
tecla := retard_tecla;
end;
end;
{############################################################################
##### E S Q U E R R A #####
############################################################################}
function i_esquerra:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
begin
i_esquerra := FALSE;
if tecla=0 then
if ((J_OK) and (joystick(joystick1_X)=joy1_MIN_X))
or (TeclaPuls(T_LEFT)) then
begin
i_esquerra := TRUE;
tecla := retard_tecla;
end;
end;
{############################################################################
##### B O T O O K #####
############################################################################}
function i_ok:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
begin
i_ok := FALSE;
if tecla=0 then
if ((J_OK) and (jbotons(button1_2)<>0))
or (TeclaPuls(T_OK)) then
begin
i_ok := TRUE;
tecla := retard_tecla+5;
end;
end;
{############################################################################
##### B O T O N O K #####
############################################################################}
function i_nok:boolean;
{ Funcio: mira si hem pulsat la tecla o el Gamepad }
begin
i_nok := FALSE;
if tecla=0 then
if ((J_OK) and (jbotons(button1_1)<>0))
or (TeclaPuls(T_NOK)) then
begin
i_nok := TRUE;
tecla := retard_tecla+5;
end;
end;
{############################################################################
##### B O T O E S C #####
############################################################################}
function i_esc:boolean;
{ Funcio: mira si hem pulsat el ESC }
begin
i_esc := FALSE;
if TeclaPuls(KeyESC) then
i_esc := TRUE;
end;
{############################################################################}
begin
Joy1_MAX_X := 144;
Joy1_MIN_X := 17;
Joy1_MAX_Y := 144;
Joy1_MIN_Y := 17;
end.
Binary file not shown.
+638
View File
@@ -0,0 +1,638 @@
{Unitat per al teclat, joystick i mouse}
{Ultima actualitzacio 19-02-2000}
unit JInput;
interface
const
(*//////////////////////////CONSTANTS DEL TECLAT\\\\\\\\\\\\\\\\\\\\\\\\*)
{El codi de SCAN es que s'activa quan es polsa una tecla}
keySysReq = $54;
keyCapsLock = $3A;
keyNumLock = $45;
keyScrollLock = $46;
keyLeftCtrl = $1D;
keyLeftAlt = $38;
keyLeftShift = $2A;
keyRightCtrl = $9D;
keyAltGr = $B8;
keyRightShift = $36;
keyEsc = $01;
keyBackspace = $0E;
keyEnter = $1C;
keySpace = $39;
keyTab = $0F;
keyF1 = $3B;
keyF2 = $3C;
keyF3 = $3D;
keyF4 = $3E;
keyF5 = $3F;
keyF6 = $40;
keyF7 = $41;
keyF8 = $42;
keyF9 = $43;
keyF10 = $44;
keyF11 = $57;
keyF12 = $58;
keyA = $1E;
keyB = $30;
keyC = $2E;
keyD = $20;
keyE = $12;
keyF = $21;
keyG = $22;
keyH = $23;
keyI = $17;
keyJ = $24;
keyK = $25;
keyL = $26;
keyM = $32;
keyN = $31;
keyO = $18;
keyP = $19;
keyQ = $10;
keyR = $13;
keyS = $1F;
keyT = $14;
keyU = $16;
keyV = $2F;
keyW = $11;
keyX = $2D;
keyY = $15;
keyZ = $2C;
key1 = $02;
key2 = $03;
key3 = $04;
key4 = $05;
key5 = $06;
key6 = $07;
key7 = $08;
key8 = $09;
key9 = $0A;
key0 = $0B;
keyMinus = $0C;
keyEqual = $0D;
keyLBracket = $1A;
keyRBracket = $1B;
keySemicolon = $27;
keyTick = $28;
keyApostrophe = $29;
keyBackslash = $2B;
keyComma = $33;
keyPeriod = $34;
keySlash = $35;
keyInsert = $D2;
keyDelete = $D3;
keyHome = $C7;
keyEnd = $CF;
keyPageUp = $C9;
keyArrowLeft = $CB;
keyArrowRight = $CD;
keyArrowUp = $C8;
keyArrowDown = $D0;
keyKeypad0 = $52;
keyKeypad1 = $4F;
keyKeypad2 = $50;
keyKeypad3 = $51;
keyKeypad4 = $4B;
keyKeypad5 = $4C;
keyKeypad6 = $4D;
keyKeypad7 = $47;
keyKeypad8 = $48;
keyKeypad9 = $49;
keyKeypadComma = $53;
keyKeypadStar = $37;
keyKeypadMinus = $4A;
keyKeypadPlus = $4E;
keyKeypadEnter = $9C;
keyCtrlPrtScr = $B7;
keyShiftPrtScr = $B7;
keyKeypadSlash = $B5;
{El codi de BREAK es el que s'activa quan es solta una tecla}
BREAK_Esc=1+128;
BREAK_1=2+128;
BREAK_2=3+128;
BREAK_3=4+128;
BREAK_4=5+128;
BREAK_5=6+128;
BREAK_6=7+128;
BREAK_7=8+128;
BREAK_8=9+128;
BREAK_9=10+128;
BREAK_0=11+128;
BREAK_Menos=12+128; {potser este siga l'apostrof}
BREAK_Igual=13+128; {potser este siga l'exclamacio}
BREAK_Backsp=14+128;
BREAK_Tab=15+128;
BREAK_Q=16+128;
BREAK_W=17+128;
BREAK_E=18+128;
BREAK_R=19+128;
BREAK_T=20+128;
BREAK_Y=21+128;
BREAK_U=22+128;
BREAK_I=23+128;
BREAK_O=24+128;
BREAK_P=25+128;
BREAK_LeftBraket=26+128;
BREAK_RightBraket=27+128;
BREAK_Enter=28+128;
BREAK_Control=29+128;
BREAK_A=30+128;
BREAK_S=31+128;
BREAK_D=32+128;
BREAK_F=33+128;
BREAK_G=34+128;
BREAK_H=35+128;
BREAK_J=36+128;
BREAK_K=37+128;
BREAK_L=38+128;
BREAK_SemiColon=39+128;{potser la ¥}
BREAK_Apostrof=40+128;{potser }
BREAK_Tilde=41+128;{potser ‡}
BREAK_LeftShift=42+128;
BREAK_Back_Slash=43+128;{potser < }
BREAK_Z=44+128;
BREAK_X=45+128;
BREAK_C=46+128;
BREAK_V=47+128;
BREAK_B=48+128;
BREAK_N=49+128;
BREAK_M=50+128;
BREAK_Coma=51+128;
BREAK_Punt=52+128;
BREAK_ForwardSlash=53+128;{potser -}
BREAK_RightShift=54+128;
BREAK_PrintScrn=55+128;
BREAK_Alt=56+128;
BREAK_Sp=57+128;
BREAK_CapsLock=58+128;
BREAK_F1=59+128;
BREAK_F2=60+128;
BREAK_F3=61+128;
BREAK_F4=62+128;
BREAK_F5=63+128;
BREAK_F6=64+128;
BREAK_F7=65+128;
BREAK_F8=66+128;
BREAK_F9=67+128;
BREAK_F10=68+128;
BREAK_F11=87+128;
BREAK_F12=88+128;
BREAK_NumLock=69+128;
BREAK_ScrollLock=70+128;
BREAK_Home=71+128;
BREAK_Up=72+128;
BREAK_PgUp=73+128;
BREAK_NumMenos=74+128;
BREAK_Left=75+128;
BREAK_Num5=76+128;
BREAK_Right=77+128;
BREAK_NumMes=78+128;
BREAK_End=79+128;
BREAK_Down=80+128;
BREAK_PgDn=81+128;
BREAK_Ins=82+128;
BREAK_Del=83+128;
{Mascares per a tecles de control cridant a int 16h}
SHIFT_R=$0001;
SHIFT_L=$0002;
CONTROL=$0004;
ALT =$0008;
SCROLL_LOCK_ON=$0010;
NUM_LOCK_ON=$0020;
CAPS_LOCK_ON=$0040;
INSERT_MODE=$0080;
CONTROL_L=$0100;
ALT_L=$0200;
CONTROL_R=$0400;
ALT_R=$0800;
SCROLL_LOCK_OFF=$1000;
NUM_LOCK_OFF=$2000;
CAPS_LOCK_OFF=$4000;
SYS_REQ_DWN=$8000;
KEYBOARD_INT=$09;
KEY_BUFFER=$60;
KEY_CONTROL=$61;
INT_CONTROL=$20;
NomTECLES:array[1..101] of PChar=
{1}('Esc','1','2','3','4','5','6','7','8','9'
{11},'0','-','=','Backsp','Tab','Q','W','E','R','T'
{21},'Y','U','I','O','P','[',']','Enter','Control','A'
{31},'S','D','F','G','H','J','K','L',';','Apostrof'
{41},'Tilde','LeftShift','\','Z','X','C','V','B','N','M'
{51},',','.','/','RightShift','Print Screen','Alt',' ','CapsLock','F1','F2'
{61},'F3','F4','F5','F6','F7','F8','F9','F10','NumLock','ScrollLock'
{71},'Home','Up','PgUp','-','Left','Num5','Right','+','End','Down'
{81},'Page Down','Insert','Del',nil,nil,nil,'F11','F12',nil,nil
{91},nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil);
(*//////////////////////////CONSTANTS DEL MOUSE\\\\\\\\\\\\\\\\\\\\\\\\*)
MBLeft=$01; {Boto esquerre del mouse}
MBRight=$02; {Boto dret del mouse}
(*/////////////////////////CONSTANTS DEL JOYSTICK\\\\\\\\\\\\\\\\\\\\\\\\*)
JoyPort=$201; {Port del Joystick}
Button1_1=$10; {boto 1 del Joystick 1}
Button1_2=$20; {boto 2 del Joystick 1}
Button2_1=$40; {boto 1 del Joystick 2}
Button2_2=$80; {boto 2 del Joystick 2}
Joystick1=$01; {ID del Joystick 1}
Joystick2=$02; {ID del Joystick 2}
Joystick1_X=$01; {Eix X del Joystick 1}
Joystick1_Y=$02; {Eix Y del Joystick 1}
Joystick2_X=$04; {Eix X del Joystick 2}
Joystick2_Y=$08; {Eix Y del Joystick 2}
Joy1_CAL=1; {ID Calibrar Joystick 1}
Joy2_CAL=2; {ID Calibrar Joystick 2}
var
{­­ ATENCIO TOTES ESTES VARIABLES SON UNICAMENT DE LECTURA !!}
{QUALSEVOL MODIFICACIO SOBRE ELLES POT CAUSAR DESASTRES I FINS I TOT
CATASTROFRES MUNDIALS.SI LES MODIFIQUES ES BAIX LA TEUA RESPONASABILITAT}
(*/////////////////////////VARIABLES DEL TECLAT\\\\\\\\\\\\\\\\\\\\\\\\*)
TECLA:word; {RESERVED}
TAULATECLES:array[1..101] of byte;{RESERVED}
OLD_KB_ISR:pointer; {Punter al antic vector d'interrupcio}
(*/////////////////////////VARIABLES DEL JOYSTICK\\\\\\\\\\\\\\\\\\\\\\\\*)
{les variables joy* guarden els valors despres de la calibracio}
{valors per al JOYSTICK1}
joy1_MAX_X, {Valor quan X es maxima DRETA}
joy1_MAX_Y, {Valor quan Y es maxima AVALL}
joy1_MIN_X, {Valor quan X es minima ESQUERRA}
joy1_MIN_Y, {Valor quan Y es minima AMUNT}
joy1_cx, {Valor quan X esta centrat}
joy1_cy, {Valor quan Y esta centrat}
{valors per al JOYSTICK2}
joy2_MAX_X, {Valor quan X es maxima DRETA}
joy2_MAX_Y, {Valor quan Y es maxima AVALL}
joy2_MIN_X, {Valor quan X es minima ESQUERRA}
joy2_MIN_Y, {Valor quan Y es minima AMUNT}
joy2_cx, {Valor quan X esta centrat}
joy2_cy:word; {Valor quan Y esta centrat}
(*/////////////////////////FUNCIONS DEL TECLAT\\\\\\\\\\\\\\\\\\\\\\\\*)
procedure InstalarKB;
{Funcio : Activa la nova interrupcio del teclat}
procedure DesinstalarKB;
{Funcio : Restaura l'antiga interrupcio del teclat}
Function TeclaPuls(Key:byte):boolean;
{Entrada: Key -> codi SCAN de tecla
Eixida : TRUE si esta polsada, FALSE si no
Funcio : Saber si una tecla esta siguent polsada}
Function QTeclaPuls:boolean;
{Eixida : TRUE si hi ha alguna tecla polsada, FALSE si no
Funcio : Saber si alguna tecla esta siguent polsada}
function AgarrarTecla:byte;
{Eixida : Codi SCAN de la tecla que esta siguent polsada
Funcio : Tornar el codi SCAN de la tecla que esta siguent polsada}
procedure EscriuTecla;
{Funcio : Escriure una cadena en pantalla depenent de la tecla}
(*/////////////////////////FUNCIONS DEL MOUSE\\\\\\\\\\\\\\\\\\\\\\\\*)
Function MouseReset:word;
{Eixida : 0,Driver instalúlat , $FFFF driver no instalúlat
Funcio : intentar activar el mouse}
Function NumButtons:word;
{Eixida : nombre de botons
Funcio : averiguar el nombre de botons del mouse}
Procedure ShowMouse;
{Funcio : Mostra el mouse en la pantalla}
Procedure HideMouse;
{Funcio : oculta el mouse}
Function GetMouseX:word;
{Eixida : Coordenada en l'eix X on es troba el mouse
Funcio : Obtindre la coordenada X del Mouse}
Function GetMouseY:word;
{Eixida : Coordenada en l'eix Y on es troba el mouse
Funcio : Obtindre la coordenada Y del Mouse}
function EstatBoto(button:word):word;
{Entrada: Codi de boto del mouse, definit en les constants
Eixida : 0 si no esta polsat, distint en cas contrari
Funcio : Saber si hi ha un boto polsat o no}
procedure SetMousePos(x,y:word);
{Entrada: Coordenada x i y on volem posar el mouse
Funcio : Colocar el mouse}
procedure SetMouseZone(x0,y0,x1,y1:word);
{Entrada: x0 -> x minima per definir la zona
y0 -> y minima per definir la zona
x1 -> x maxima per definir la zona
y1 -> y maxima per definir la zona
Funcio : Tancar al mouse dins d'una zona per que no isca}
procedure SetMouseInterruptRate(Code:word);
{Entrada: Code
0 No interrupts
1 30 ints per second
2 50 ints per second
3 100 ints per second
4 200 ints per second
Funcio : Canviar les peticions d'interrupcio que fa el mouse}
procedure SetMouseSensitivity(Xsens,Ysens:word);
{Entrada: XSens -> (1..32767)
Ysens -> (1..32767)
Funcio : Canviar la sensitivitat de mouse}
procedure SetMouseDoubleSpeed(Speed:word);
{Entrada: Speed -> velocitat en mickeys per segon
Funcio : Canviar la velocitat}
(*/////////////////////////FUNCIONS DEL JOYSTICK\\\\\\\\\\\\\\\\\\\\\\\\*)
function JBotons(button:word):word;
{Entrada: button -> Codi del boto
Eixida : 0, boto no polsat <>0,boto polsat
Funcio : Averiguar si un boto esta polsat}
function Joystick(stick:word):word;
{Entrada: Stick -> JOYSTICK?_? constants dalt definides
Eixida : Valor que podem comparar en el valor de les variables de calibracio
Funcio : Torna un valor depenent de l'estat de l'eix }
Procedure JoyCalibrate(stick:word);
{Entrada: stick -> Codi del Joystick (Joy1_CAL o Joy2_CAL)
Funcio : Calibrar el joystick}
function JoyAvaliable(stick:word):boolean;
{Entrada: stick -> Codi del Joystick (Joystick1 o Joystick2)
Eixida : FLASE si no hi detecta un joystick
Funcio : Averiguar si hi ha un joystick}
implementation
uses dos;
(*/////////////////////////FUNCIONS DEL TECLAT\\\\\\\\\\\\\\\\\\\\\\\\*)
procedure NEWKB;interrupt;assembler;
asm
cli
in al, KEY_BUFFER {obtindre la tecla polsada}
xor ah,ah
mov TECLA,ax {guardar la tecla}
in al,KEY_CONTROL {accedir al registre de control}
or al,82h {posar els bits adequats per fer un reset
en el biestable del teclat}
out KEY_CONTROL,al {enviar les noves dades al registre}
and al,7Fh
out KEY_CONTROL,al {Fer el reset}
{Actualitzacio de la taula de tecles}
mov bx,tecla
cmp bx,128
jg @breakcode
mov byte ptr TAULATECLES[bx-1],1
jmp @end
@breakcode:
sub bx,128
mov byte ptr TAULATECLES[bx-1],0
@end:
mov al,20h
out INT_CONTROL,al
sti
end;
procedure waitACS;
begin
asm
mov ah,2
int 16h
and al,00001111b
jz @fi
@espera:
mov ah,2
int 16h
and al,00001111b {al->bit 7=Insert On
6=Caps Lock on
5=Num Lock on
4=scroll lock on
3=Alt key down
2=Control key down
1=left shift down
0=right shift down}
jnz @espera
@fi:
end;
end;
procedure InstalarKB;
var i:word;
begin
waitACS;
getintvec(KEYBOARD_INT,Old_KB_ISR);
setintvec(KEYBOARD_INT,@NEWKB);
Fillchar(TAULATECLES,sizeof(Taulatecles),0);
end;
procedure desinstalarKB;
begin
setintvec(KEYBOARD_INT,OLD_KB_ISR);
end;
Function TeclaPuls(Key:byte):boolean;
begin
if TAULATECLES[KEY]=1 then TeclaPuls:=TRUE else TeclaPuls:=FALSE;
end;
Function QTeclaPuls:boolean;
begin
if tecla>=128 then QTeclaPuls:=false else QTeclaPuls:=true;
end;
function AgarrarTecla:byte;
begin
if tecla<101 then AgarrarTecla:=tecla;
end;
procedure EscriuTecla;
begin
if tecla<128 then write(NomTecles[tecla]);
end;
(*/////////////////////////FUNCIONS DEL MOUSE\\\\\\\\\\\\\\\\\\\\\\\\*)
Function MouseReset:word;assembler;
{MouseReset=0 Driver no instalúlat}
{MouseReset=65535 Driver instalúlat}
asm
xor ax,ax
int 33h
end;
Function NumButtons:word;assembler;
asm
xor ax,ax
int 33h
mov ax,bx
end;
Procedure ShowMouse;assembler;
asm
mov ax,0001h
int 33h
end;
Procedure HideMouse;assembler;
asm
mov ax,0002h
int 33h
end;
Function GetMouseX:word;assembler;
{x -> (0..639)}
asm
mov ax,$0003
int 33h
mov ax,cx
end;
Function GetMouseY:word;assembler;
{y -> (0..199)}
asm
mov ax,$0003
int 33h
mov ax,dx
end;
function EstatBoto(button:word):word;assembler;
{Torna <>0 si esta polsat}
asm
mov ax,$0003
int 33h
mov ax,bx
and ax,button
end;
procedure SetMousePos(x,y:word);assembler;
asm
mov ax,$0004
mov cx,x
mov dx,y
int 33h
end;
procedure SetMouseZone(x0,y0,x1,y1:word);assembler;
asm
mov ax,$0007
mov cx,x0
mov dx,x1
int 33h
mov ax,$0008
mov cx,y0
mov dx,y1
int 33h
end;
procedure SetMouseInterruptRate(Code:word);assembler;
{Code
0 No interrupts
1 30 ints per second
2 50 ints per second
3 100 ints per second
4 200 ints per second
}
asm
mov ax,$001C
mov bx,code
int 33h
end;
procedure SetMouseSensitivity(Xsens,Ysens:word);assembler;
{XSens (1..32767}
{Ysens (1..32767}
asm
mov ax,$000F
mov cx,Xsens
mov dx,Ysens
int 33h
end;
procedure SetMouseDoubleSpeed(Speed:word);assembler;
asm
mov ax,$0013
mov dx,speed
int 33h
end;
(*/////////////////////////FUNCIONS DEL JOYSTICK\\\\\\\\\\\\\\\\\\\\\\\\*)
function JBotons(button:word):word;
begin
Port[Joyport]:=0;
JBotons:=(not Port[Joyport]) and Button;
end;
function Joystick(stick:word):word;assembler;
asm
cli
mov ah,byte ptr stick
xor al,al
xor cx,cx
mov dx,JOYPORT
out dx,al
@discharge:
in al,dx
test al,ah
loopne @discharge
sti
xor ax,ax
sub ax,cx
end;
Procedure JoyCalibrate(stick:word);
var xnew,ynew:word;
begin
if (Stick=JOY1_CAL) then
begin
joy1_MAX_X:=0;
joy1_MAX_Y:=0;
joy1_MIN_X:=10000;
joy1_MIN_Y:=10000;
{girar, deixar neutral i polsar un boto}
while (JBotons(button1_1) or JBotons(button1_2))=0 do
begin
xnew:=Joystick(Joystick1_X);
ynew:=Joystick(Joystick1_Y);
if (xnew>=joy1_Max_x) then joy1_Max_X:=xnew;
if (xnew<=joy1_Min_x) then joy1_Min_X:=xnew;
if (ynew>=joy1_Max_y) then joy1_Max_y:=ynew;
if (ynew<=joy1_Min_y) then joy1_Min_y:=ynew;
end;
{com l'usuari ha deixat el pad al centre deu estar al centre}
Joy1_cx:=xnew;
Joy1_cy:=ynew;
end
else if (stick=JOY2_CAL) then
begin
joy2_MAX_X:=0;
joy2_MAX_Y:=0;
joy2_MIN_X:=10000;
joy2_MIN_Y:=10000;
while (JBotons(button2_1) or JBotons(button2_2))=0 do
begin
xnew:=Joystick(Joystick2_X);
ynew:=Joystick(Joystick2_Y);
if (xnew>=joy2_Max_x) then joy2_Max_X:=xnew;
if (xnew<=joy2_Min_x) then joy2_Min_X:=xnew;
if (ynew>=joy2_Max_y) then joy2_Max_y:=ynew;
if (ynew<=joy2_Min_y) then joy2_Max_y:=ynew;
end;
{com l'usuari ha deixat el pad al centre deu estar al centre}
Joy2_cx:=xnew;
Joy2_cy:=ynew;
end;
end;
function JoyAvaliable(stick:word):boolean;
{torna un valor distint de 0 si existeix}
begin
if (stick=JOYSTICK1) then
JoyAvaliable:=(Joystick(Joystick1_X)<>$0000)
else if (stick=JOYSTICK2) then
JoyAvaliable:=(Joystick(Joystick2_X)<>$0000);
end;
begin
tecla:=128;
end.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+756
View File
@@ -0,0 +1,756 @@
uses grafix, jinput, utext, tipos, crt;
procedure FaseNova;forward;
{##############################################################}
{# O F F S E T M A P A #}
{##############################################################}
function OffsetMapa:longint;
var i:longint;
marca : integer;
fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
marca := 0;
repeat
Read(fich, buffer);
if buffer = ord('*') then
inc(marca)
else
marca := 0;
inc(i);
until (marca = 10);
OffsetMapa := i;
end;
{##############################################################}
{# C A R R E G A R E C O R D S #}
{##############################################################}
procedure CarregaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'records');
Reset(fich);
{Seek(fich, FileSize(fich)-6);}
Read(fich, buffer); { centenes }
hi_score := buffer * 100;
Read(fich, buffer); { decenes }
hi_score := score + (buffer * 10);
Read(fich, buffer); { unitats }
hi_score := score + buffer;
Read(fich, buffer); { 1¦ lletra }
nom_hi_score := chr(buffer);
Read(fich, buffer); { 2¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer);
Read(fich, buffer); { 3¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer);
Close(fich);
end;
{##############################################################}
{# G U A R D A R E C O R D S #}
{##############################################################}
procedure GuardaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'records');
Reset(fich);
{Seek(fich, FileSize(fich)-6);}
buffer := score div 100;
Write(fich, buffer); { centenes }
buffer := (score - (buffer*100)) div 10;
Write(fich, buffer); { decenes }
buffer := (score - (buffer*10));
Write(fich, buffer); { unitats }
buffer := ord(nom_hi_score[1]);
Write(fich, buffer); { 1¦ lletra }
buffer := ord(nom_hi_score[2]);
Write(fich, buffer); { 2¦ lletra }
buffer := ord(nom_hi_score[3]);
Write(fich, buffer); { 3¦ lletra }
Close(fich);
end;
{##############################################################}
{# T R A G A P A N T A L L A #}
{##############################################################}
procedure TragaPantalla;
begin
for k:=0 to 23 do
begin
{ despla‡a cap avall }
for i:=0 to 39 do
for j:=23 downto 1 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j-1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j-1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(13,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
end;
end;
{##############################################################}
{# P O S A R N O M #}
{##############################################################}
procedure PosarNom;
var index : integer;
Key : byte;
Tecla : Pchar;
begin
nom_hi_score := '...';
index := 1;
PutStringCENTERED(13, 15, 'Enhorabona, has');
PutStringCENTERED(14, 15, 'aconseguit un nou record');
PutStringCENTERED(16, 15, nom_hi_score);
repeat
if QTeclaPuls then
begin
Key := AgarrarTecla;
Tecla := nomTECLES[Key];
nom_hi_score[index] := Tecla^;
inc(index);
PutStringCENTERED(16, 15, nom_hi_score);
repeat until not(QTeclaPuls);
end;
until (index = 4);
GuardaRecords;
end;
{##############################################################}
{# G A M E O V E R #}
{##############################################################}
procedure GameOver;
begin
TragaPantalla;
cls($B800);
PutStringCENTERED(10, 15, 'G A M E O V E R');
for i:=0 to 100 do espera_VGA;
if score > hi_score then PosarNom;
FadeDown(0,0,0,0);
end;
{##############################################################}
{# F I N A L P A N T A L L A #}
{##############################################################}
procedure FinalPantalla;
begin
TragaPantalla;
FaseNova;
end;
{##############################################################}
{# M O R T #}
{##############################################################}
procedure Mort;
begin
dec(pepe.vides);
pepe.posX := 19;
pepe.posY := 23;
end;
{##############################################################}
{# M O R T M A L O #}
{##############################################################}
procedure MortMalo(num: byte);
begin
malo[num].posX := 39;
malo[num].posY := 1;
malo[num].color := 3;
malo[num].estat := caent;
malo[num].IAclock := 0;
mapa[malo[num].carrega.posX, malo[num].carrega.posY].tipo := diners;
malo[num].carrega.OK := false;
malo[num].carrega.posX := 0;
malo[num].carrega.posY := 0;
end;
{##############################################################}
{# F O R A D A R #}
{##############################################################}
procedure Foradar(posX, posY : word);
begin
{ mapa[posX, posY].tipo := buit;}
mapa[posX, posY].temps := bloc_out;
end;
{##############################################################}
{# M O U P E P E #}
{##############################################################}
procedure MouPepe;
var hi_ha_malo_baix : boolean;
begin
if TeclaPuls(KeyQ) then
begin
if mapa[pepe.posX, pepe.posY].tipo=escala then
begin
dec(pepe.posY);
end;
end
else
if TeclaPuls(KeyA) then
begin
if (mapa[pepe.posX, pepe.posY+1].tipo=escala) or (mapa[pepe.posX, pepe.posY+1].tipo=buit) then
inc(pepe.posY);
end;
if TeclaPuls(KeyO) then
begin
if (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
dec(pepe.posX);
end
else
if TeclaPuls(KeyP) then
begin
if (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
inc(pepe.posX);
end
else
if TeclaPuls(KeySPACE) then
begin
if (mapa[pepe.posX-1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX-1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX-1, pepe.posY+1);
end
else
if TeclaPuls(KeyM) then
begin
if (mapa[pepe.posX+1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX+1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX+1, pepe.posY+1);
end;
{ si no passa res... }
pepe.estat := normal;
{ final pantalla }
if pepe.posY = 1 then FinalPantalla;
{ emparedat }
if mapa[pepe.posX, pepe.posY].tipo = pedra then
Mort;
{ agarra diners }
if mapa[pepe.posX, pepe.posY].tipo = diners then
begin
mapa[pepe.posX, pepe.posY].tipo := buit;
inc(score);
dec(diners_pantalla);
end;
{ bordes X pantalla }
if pepe.posX<0 then pepe.posX:=0;
if pepe.posX>39 then pepe.posX:=39;
{ gravetat }
if ((mapa[pepe.posX, pepe.posY+1].tipo<>escala) and (mapa[pepe.posX, pepe.posY+1].tipo<>pedra))
and ((mapa[pepe.posX, pepe.posY].tipo=buit) or (mapa[pepe.posX, pepe.posY].tipo=diners)) then
begin
hi_ha_malo_baix := FALSE;
for i:=0 to num_malos-1 do
if (pepe.posX = malo[i].posX) and (pepe.posY+1 = malo[i].posY) then
hi_ha_malo_baix := TRUE;
if not(hi_ha_malo_baix) then
begin
inc(pepe.posY);
pepe.estat := caent;
end;
end;
{ bordes Y pantalla }
if pepe.posY<0 then pepe.posY:=0;
if pepe.posY>24 then pepe.posY:=24;
end;
{##############################################################}
{# S E L E C T E S T A T #}
{##############################################################}
function SelectEstat(num: byte):byte;
var nou_estat : byte;
Sestat:byte;
x:byte;
estat_pX,estat_pY:byte;
buscar:byte;
begin
nou_estat := 0;
Sestat:=0;
if mapa[malo[num].posX+1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+dreta;
if mapa[malo[num].posX-1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+esquerra;
if mapa[malo[num].posX, malo[num].posY].tipo = escala then
nou_estat := nou_estat + pujar;
if mapa[malo[num].posX, malo[num].posY+1].tipo = escala then
nou_estat := nou_estat + baixar;
if nou_estat=0 then Sestat:=10; {no pot moure's}
if malo[num].posX>pepe.posX then estat_pX:=esquerra
else estat_pX:=dreta;
if malo[num].posY>pepe.posY then estat_pY:=pujar
else estat_pY:=baixar;
x:=random(4);
buscar:=random(100);
if (buscar<50) and ((nou_estat and estat_PX=estat_PX) or
(nou_estat and estat_PY=estat_PY)) then
begin
if (nou_estat and estat_PX=estat_PX) then Sestat:=estat_PX
else Sestat:=estat_PY;
end
else
repeat
case x of
0:if nou_estat and dreta =dreta then Sestat:=dreta;
1:if nou_estat and esquerra =esquerra then Sestat:=esquerra;
2:if nou_estat and pujar =pujar then Sestat:=pujar;
3:if nou_estat and baixar =baixar then Sestat:=baixar;
end;
inc(x);
x:=x and $03;
until Sestat<>0;
SelectEstat:=Sestat;
if (mapa[malo[num].posX, malo[num].posY+1].tipo <> pedra)
and (mapa[malo[num].posX, malo[num].posY+1].tipo <> escala) then
SelectEstat:=caent;
end;
{##############################################################}
{# A G A F A R E S C A L A #}
{##############################################################}
function AgafarEscala(num:byte):byte;
var x:byte;
ag:boolean;
estat:byte;
begin
estat:=malo[num].estat;
if (estat=dreta) or (estat=esquerra) then
begin
x:=random(100);
if x<80 then ag:=True else ag:=false;
if ag then
begin
if (mapa[malo[num].posX, malo[num].posY].tipo = escala) then
estat:=pujar
else
if (mapa[malo[num].posX, malo[num].posY+1].tipo = escala) then
estat:=baixar;
end;
end;
AgafarEscala:=estat;
end;
{##############################################################}
{# M O U M A L O S #}
{##############################################################}
procedure MouMalos;
begin
for i:=0 to num_malos-1 do
begin
if malo[i].IAclock = 0 then
malo[i].estat := SelectEstat(i);
malo[i].estat:=AgafarEscala(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo <> pedra) and
(mapa[malo[i].posX, malo[i].posY+1].tipo <> escala)) and
(mapa[malo[i].posX, malo[i].posY].tipo <> corda) then
malo[i].estat:=caent;
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) or
(mapa[malo[i].posX, malo[i].posY+1].tipo = escala)) and
(malo[i].estat=caent) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY].tipo = buit) and
(malo[i].estat=pujar)) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) and
(malo[i].estat=baixar)) then
malo[i].estat:=SelectEstat(i);
case malo[i].estat of
dreta : inc(malo[i].posX);
esquerra : dec(malo[i].posX);
pujar : dec(malo[i].posY);
baixar : inc(malo[i].posY);
caent : inc(malo[i].posY);
end;
{ bordes X }
if malo[i].posX<0 then
begin
malo[i].posX:=0;
malo[i].estat := dreta;
end;
if malo[i].posX>39 then
begin
malo[i].posX:=39;
malo[i].estat := esquerra;
end;
{ bordes Y }
if malo[i].posY<0 then
begin
malo[i].posY:=0;
end;
if malo[i].posY>24 then
begin
malo[i].posY:=24;
end;
{ agarrar diners }
if (mapa[malo[i].posX, malo[i].posY].tipo = diners)
and not(malo[i].carrega.OK) then
begin
mapa[malo[i].posX, malo[i].posY].tipo := buit;
malo[i].color := 11;
malo[i].carrega.OK := TRUE;
malo[i].carrega.posX := malo[i].posX;
malo[i].carrega.posY := malo[i].posY;
end;
{ emparedat }
if mapa[malo[i].posX, malo[i].posY].tipo = pedra then
MortMalo(i);
inc(malo[i].IAclock);
if malo[i].IAclock = temps_IA then malo[i].IAclock := 0;
end;
end;
{##############################################################}
{# C A R R E G A M A P A #}
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'total.map');
Reset(fich);
Seek(fich, (level * 1000)+offset_mapa);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo:=buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
{# C H E C K M O R T P E R M A L O S #}
{##############################################################}
procedure CheckMortPerMalos;
begin
for i:=0 to num_malos-1 do
if (malo[i].posX = pepe.posX) and (malo[i].posY = pepe.posY) then
Mort;
end;
{##############################################################}
{# C H E C K M A P A C O M P L E T #}
{##############################################################}
procedure CheckMapaComplet;
begin
if diners_pantalla = 0 then
for j:=1 to 23 do
begin
if mapa[0,j].tipo <> pedra then
begin
mapa[0,j].tipo := escala;
mapa[0,j].color := color_escala;
end
else
break;
end;
end;
{##############################################################}
{# C H E C K M A P A #}
{##############################################################}
procedure CheckMapa;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
case mapa[i,j].temps of
0 : begin
mapa[i,j].temps := -1;
mapa[i,j].tipo := pedra;
end;
1,bloc_out-1 : begin
mapa[i,j].tipo := bloc3;
dec(mapa[i,j].temps)
end;
2,bloc_out-2 : begin
mapa[i,j].tipo := bloc2;
dec(mapa[i,j].temps)
end;
3,bloc_out-3 : begin
mapa[i,j].tipo := bloc1;
dec(mapa[i,j].temps)
end;
4,bloc_out-4 : begin
mapa[i,j].tipo := buit;
dec(mapa[i,j].temps)
end;
-1 : ;
else dec(mapa[i,j].temps)
end;
end;
CheckMapaComplet;
end;
{##############################################################}
{# F A S E N O V A #}
{##############################################################}
procedure FaseNova;
begin
inc(level);
if level=(num_fases + 1) then
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# I N I C I A L I T Z A C I O #}
{##############################################################}
procedure Inicialitzacio;
begin
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
pepe.vides := 0;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# T I T O L #}
{##############################################################}
procedure Titol;
begin
getpaleta(paleta);
blackout;
PutStringCENTERED(10, 15, 'JAILDESIGNER');
PutStringCENTERED(12, 15, 'presenta');
FadeUp(paleta, 1);
for i:=0 to 100 do espera_VGA;
Fadedown(0,0,0,0);
level := 0;
CarregaMapa;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
move(mem[pant1:0], mem[$B800:0], 2000);
FadeUp(paleta, 0);
for i:=0 to 100 do espera_VGA;
for k:=0 to 2 do
begin
{ despla‡a cap amunt }
for i:=0 to 39 do
for j:=0 to 23 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j+1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j+1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
end;
end;
{##############################################################}
{# M E N U #}
{##############################################################}
procedure Menu;
var num : integer;
begin
num := 1;
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'OPCIONS');
repeat
repeat until QteclaPuls;
if (TeclaPuls(KeyA)) then
num := 2;
if (TeclaPuls(KeyQ)) then
num := 1;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
if num = 1 then
begin
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
end
else
begin
PutStringCENTERED(18, 15, 'COMEN€AR JOC');
PutStringWINDOWED(20, 14, 'EIXIR');
end;
until TeclaPuls(KeyENTER);
if num = 2 then
{ menu d'opcions }
exit_game := TRUE;
;
end;
{##############################################################}
begin
instalarKB;
setmode(1);
HideCursor;
SetUpVirtual(ptrpant1, pant1);
randomize;
offset_mapa := OffsetMapa;
exit_game := FALSE;
repeat
Titol;
Menu;
Inicialitzacio;
CarregaRecords;
repeat
MouPepe;
CheckMortPerMalos;
if (Clock mod 4) = 0 then MouMalos;
CheckMortPerMalos;
PintaPantalla;
CheckMapa;
until TeclaPuls(KeyESC) or (Pepe.vides<0);
GameOver;
until exit_game;
TancarVirtual(ptrpant1);
setmode(3);
desinstalarKB;
end.
Binary file not shown.
+756
View File
@@ -0,0 +1,756 @@
uses grafix, jinput, utext, tipos, crt;
procedure FaseNova;forward;
{##############################################################}
{# O F F S E T M A P A #}
{##############################################################}
function OffsetMapa:longint;
var i:longint;
marca : integer;
fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
marca := 0;
repeat
Read(fich, buffer);
if buffer = ord('*') then
inc(marca)
else
marca := 0;
inc(i);
until (marca = 10);
OffsetMapa := i;
end;
{##############################################################}
{# C A R R E G A R E C O R D S #}
{##############################################################}
procedure CarregaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'records');
Reset(fich);
{Seek(fich, FileSize(fich)-6);}
Read(fich, buffer); { centenes }
hi_score := buffer * 100;
Read(fich, buffer); { decenes }
hi_score := score + (buffer * 10);
Read(fich, buffer); { unitats }
hi_score := score + buffer;
Read(fich, buffer); { 1¦ lletra }
nom_hi_score := chr(buffer);
Read(fich, buffer); { 2¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer);
Read(fich, buffer); { 3¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer);
Close(fich);
end;
{##############################################################}
{# G U A R D A R E C O R D S #}
{##############################################################}
procedure GuardaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'records');
Reset(fich);
{Seek(fich, FileSize(fich)-6);}
buffer := score div 100;
Write(fich, buffer); { centenes }
buffer := (score - (buffer*100)) div 10;
Write(fich, buffer); { decenes }
buffer := (score - (buffer*10));
Write(fich, buffer); { unitats }
buffer := ord(nom_hi_score[1]);
Write(fich, buffer); { 1¦ lletra }
buffer := ord(nom_hi_score[2]);
Write(fich, buffer); { 2¦ lletra }
buffer := ord(nom_hi_score[3]);
Write(fich, buffer); { 3¦ lletra }
Close(fich);
end;
{##############################################################}
{# T R A G A P A N T A L L A #}
{##############################################################}
procedure TragaPantalla;
begin
for k:=0 to 23 do
begin
{ despla‡a cap avall }
for i:=0 to 39 do
for j:=23 downto 1 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j-1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j-1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(13,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
end;
end;
{##############################################################}
{# P O S A R N O M #}
{##############################################################}
procedure PosarNom;
var index : integer;
Key : byte;
Tecla : Pchar;
begin
nom_hi_score := '...';
index := 1;
PutStringCENTERED(13, 15, 'Enhorabona, has');
PutStringCENTERED(14, 15, 'aconseguit un nou record');
PutStringCENTERED(16, 15, nom_hi_score);
repeat
if QTeclaPuls then
begin
Key := AgarrarTecla;
Tecla := nomTECLES[Key];
nom_hi_score[index] := Tecla^;
inc(index);
PutStringCENTERED(16, 15, nom_hi_score);
repeat until not(QTeclaPuls);
end;
until (index = 4);
GuardaRecords;
end;
{##############################################################}
{# G A M E O V E R #}
{##############################################################}
procedure GameOver;
begin
TragaPantalla;
cls($B800);
PutStringCENTERED(10, 15, 'G A M E O V E R');
for i:=0 to 100 do espera_VGA;
if score > hi_score then PosarNom;
FadeDown(0,0,0,0);
end;
{##############################################################}
{# F I N A L P A N T A L L A #}
{##############################################################}
procedure FinalPantalla;
begin
TragaPantalla;
FaseNova;
end;
{##############################################################}
{# M O R T #}
{##############################################################}
procedure Mort;
begin
dec(pepe.vides);
pepe.posX := 19;
pepe.posY := 23;
end;
{##############################################################}
{# M O R T M A L O #}
{##############################################################}
procedure MortMalo(num: byte);
begin
malo[num].posX := 39;
malo[num].posY := 1;
malo[num].color := 3;
malo[num].estat := caent;
malo[num].IAclock := 0;
mapa[malo[num].carrega.posX, malo[num].carrega.posY].tipo := diners;
malo[num].carrega.OK := false;
malo[num].carrega.posX := 0;
malo[num].carrega.posY := 0;
end;
{##############################################################}
{# F O R A D A R #}
{##############################################################}
procedure Foradar(posX, posY : word);
begin
{ mapa[posX, posY].tipo := buit;}
mapa[posX, posY].temps := bloc_out;
end;
{##############################################################}
{# M O U P E P E #}
{##############################################################}
procedure MouPepe;
var hi_ha_malo_baix : boolean;
begin
if TeclaPuls(KeyQ) then
begin
if mapa[pepe.posX, pepe.posY].tipo=escala then
begin
dec(pepe.posY);
end;
end
else
if TeclaPuls(KeyA) then
begin
if (mapa[pepe.posX, pepe.posY+1].tipo=escala) or (mapa[pepe.posX, pepe.posY+1].tipo=buit) then
inc(pepe.posY);
end;
if TeclaPuls(KeyO) then
begin
if (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
dec(pepe.posX);
end
else
if TeclaPuls(KeyP) then
begin
if (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
inc(pepe.posX);
end
else
if TeclaPuls(KeySPACE) then
begin
if (mapa[pepe.posX-1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX-1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX-1, pepe.posY+1);
end
else
if TeclaPuls(KeyM) then
begin
if (mapa[pepe.posX+1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX+1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX+1, pepe.posY+1);
end;
{ si no passa res... }
pepe.estat := normal;
{ final pantalla }
if pepe.posY = 1 then FinalPantalla;
{ emparedat }
if mapa[pepe.posX, pepe.posY].tipo = pedra then
Mort;
{ agarra diners }
if mapa[pepe.posX, pepe.posY].tipo = diners then
begin
mapa[pepe.posX, pepe.posY].tipo := buit;
inc(score);
dec(diners_pantalla);
end;
{ bordes X pantalla }
if pepe.posX<0 then pepe.posX:=0;
if pepe.posX>39 then pepe.posX:=39;
{ gravetat }
if ((mapa[pepe.posX, pepe.posY+1].tipo<>escala) and (mapa[pepe.posX, pepe.posY+1].tipo<>pedra))
and ((mapa[pepe.posX, pepe.posY].tipo=buit) or (mapa[pepe.posX, pepe.posY].tipo=diners)) then
begin
hi_ha_malo_baix := FALSE;
for i:=0 to num_malos-1 do
if (pepe.posX = malo[i].posX) and (pepe.posY+1 = malo[i].posY) then
hi_ha_malo_baix := TRUE;
if not(hi_ha_malo_baix) then
begin
inc(pepe.posY);
pepe.estat := caent;
end;
end;
{ bordes Y pantalla }
if pepe.posY<0 then pepe.posY:=0;
if pepe.posY>24 then pepe.posY:=24;
end;
{##############################################################}
{# S E L E C T E S T A T #}
{##############################################################}
function SelectEstat(num: byte):byte;
var nou_estat : byte;
Sestat:byte;
x:byte;
estat_pX,estat_pY:byte;
buscar:byte;
begin
nou_estat := 0;
Sestat:=0;
if mapa[malo[num].posX+1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+dreta;
if mapa[malo[num].posX-1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+esquerra;
if mapa[malo[num].posX, malo[num].posY].tipo = escala then
nou_estat := nou_estat + pujar;
if mapa[malo[num].posX, malo[num].posY+1].tipo = escala then
nou_estat := nou_estat + baixar;
if nou_estat=0 then Sestat:=10; {no pot moure's}
if malo[num].posX>pepe.posX then estat_pX:=esquerra
else estat_pX:=dreta;
if malo[num].posY>pepe.posY then estat_pY:=pujar
else estat_pY:=baixar;
x:=random(4);
buscar:=random(100);
if (buscar<50) and ((nou_estat and estat_PX=estat_PX) or
(nou_estat and estat_PY=estat_PY)) then
begin
if (nou_estat and estat_PX=estat_PX) then Sestat:=estat_PX
else Sestat:=estat_PY;
end
else
repeat
case x of
0:if nou_estat and dreta =dreta then Sestat:=dreta;
1:if nou_estat and esquerra =esquerra then Sestat:=esquerra;
2:if nou_estat and pujar =pujar then Sestat:=pujar;
3:if nou_estat and baixar =baixar then Sestat:=baixar;
end;
inc(x);
x:=x and $03;
until Sestat<>0;
SelectEstat:=Sestat;
if (mapa[malo[num].posX, malo[num].posY+1].tipo <> pedra)
and (mapa[malo[num].posX, malo[num].posY+1].tipo <> escala) then
SelectEstat:=caent;
end;
{##############################################################}
{# A G A F A R E S C A L A #}
{##############################################################}
function AgafarEscala(num:byte):byte;
var x:byte;
ag:boolean;
estat:byte;
begin
estat:=malo[num].estat;
if (estat=dreta) or (estat=esquerra) then
begin
x:=random(100);
if x<80 then ag:=True else ag:=false;
if ag then
begin
if (mapa[malo[num].posX, malo[num].posY].tipo = escala) then
estat:=pujar
else
if (mapa[malo[num].posX, malo[num].posY+1].tipo = escala) then
estat:=baixar;
end;
end;
AgafarEscala:=estat;
end;
{##############################################################}
{# M O U M A L O S #}
{##############################################################}
procedure MouMalos;
begin
for i:=0 to num_malos-1 do
begin
if malo[i].IAclock = 0 then
malo[i].estat := SelectEstat(i);
malo[i].estat:=AgafarEscala(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo <> pedra) and
(mapa[malo[i].posX, malo[i].posY+1].tipo <> escala)) and
(mapa[malo[i].posX, malo[i].posY].tipo <> corda) then
malo[i].estat:=caent;
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) or
(mapa[malo[i].posX, malo[i].posY+1].tipo = escala)) and
(malo[i].estat=caent) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY].tipo = buit) and
(malo[i].estat=pujar)) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) and
(malo[i].estat=baixar)) then
malo[i].estat:=SelectEstat(i);
case malo[i].estat of
dreta : inc(malo[i].posX);
esquerra : dec(malo[i].posX);
pujar : dec(malo[i].posY);
baixar : inc(malo[i].posY);
caent : inc(malo[i].posY);
end;
{ bordes X }
if malo[i].posX<0 then
begin
malo[i].posX:=0;
malo[i].estat := dreta;
end;
if malo[i].posX>39 then
begin
malo[i].posX:=39;
malo[i].estat := esquerra;
end;
{ bordes Y }
if malo[i].posY<0 then
begin
malo[i].posY:=0;
end;
if malo[i].posY>24 then
begin
malo[i].posY:=24;
end;
{ agarrar diners }
if (mapa[malo[i].posX, malo[i].posY].tipo = diners)
and not(malo[i].carrega.OK) then
begin
mapa[malo[i].posX, malo[i].posY].tipo := buit;
malo[i].color := 11;
malo[i].carrega.OK := TRUE;
malo[i].carrega.posX := malo[i].posX;
malo[i].carrega.posY := malo[i].posY;
end;
{ emparedat }
if mapa[malo[i].posX, malo[i].posY].tipo = pedra then
MortMalo(i);
inc(malo[i].IAclock);
if malo[i].IAclock = temps_IA then malo[i].IAclock := 0;
end;
end;
{##############################################################}
{# C A R R E G A M A P A #}
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'total.map');
Reset(fich);
Seek(fich, (level * 1000)+offset_mapa);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo:=buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
{# C H E C K M O R T P E R M A L O S #}
{##############################################################}
procedure CheckMortPerMalos;
begin
for i:=0 to num_malos-1 do
if (malo[i].posX = pepe.posX) and (malo[i].posY = pepe.posY) then
Mort;
end;
{##############################################################}
{# C H E C K M A P A C O M P L E T #}
{##############################################################}
procedure CheckMapaComplet;
begin
if diners_pantalla = 0 then
for j:=1 to 23 do
begin
if mapa[0,j].tipo <> pedra then
begin
mapa[0,j].tipo := escala;
mapa[0,j].color := color_escala;
end
else
break;
end;
end;
{##############################################################}
{# C H E C K M A P A #}
{##############################################################}
procedure CheckMapa;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
case mapa[i,j].temps of
0 : begin
mapa[i,j].temps := -1;
mapa[i,j].tipo := pedra;
end;
1,bloc_out-1 : begin
mapa[i,j].tipo := bloc3;
dec(mapa[i,j].temps)
end;
2,bloc_out-2 : begin
mapa[i,j].tipo := bloc2;
dec(mapa[i,j].temps)
end;
3,bloc_out-3 : begin
mapa[i,j].tipo := bloc1;
dec(mapa[i,j].temps)
end;
4,bloc_out-4 : begin
mapa[i,j].tipo := buit;
dec(mapa[i,j].temps)
end;
-1 : ;
else dec(mapa[i,j].temps)
end;
end;
CheckMapaComplet;
end;
{##############################################################}
{# F A S E N O V A #}
{##############################################################}
procedure FaseNova;
begin
inc(level);
if level=(num_fases + 1) then
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# I N I C I A L I T Z A C I O #}
{##############################################################}
procedure Inicialitzacio;
begin
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
pepe.vides := 0;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# T I T O L #}
{##############################################################}
procedure Titol;
begin
getpaleta(paleta);
blackout;
PutStringCENTERED(10, 15, 'JAILDESIGNER');
PutStringCENTERED(12, 15, 'presenta');
FadeUp(paleta, 1);
for i:=0 to 100 do espera_VGA;
Fadedown(0,0,0,0);
level := 0;
CarregaMapa;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
move(mem[pant1:0], mem[$B800:0], 2000);
FadeUp(paleta, 0);
for i:=0 to 100 do espera_VGA;
for k:=0 to 2 do
begin
{ despla‡a cap amunt }
for i:=0 to 39 do
for j:=0 to 23 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j+1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j+1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
end;
end;
{##############################################################}
{# M E N U #}
{##############################################################}
procedure Menu;
var num : integer;
begin
num := 1;
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'OPCIONS');
repeat
repeat until QteclaPuls;
if (TeclaPuls(KeyA)) then
num := 2;
if (TeclaPuls(KeyQ)) then
num := 1;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
if num = 1 then
begin
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
end
else
begin
PutStringCENTERED(18, 15, 'COMEN€AR JOC');
PutStringWINDOWED(20, 14, 'EIXIR');
end;
until TeclaPuls(KeyENTER);
if num = 2 then
{ menu d'opcions }
exit_game := TRUE;
;
end;
{##############################################################}
begin
instalarKB;
setmode(1);
HideCursor;
SetUpVirtual(ptrpant1, pant1);
randomize;
offset_mapa := OffsetMapa;
exit_game := FALSE;
repeat
{Titol;
Menu;}
Inicialitzacio;
CarregaRecords;
repeat
MouPepe;
CheckMortPerMalos;
if (Clock mod 4) = 0 then MouMalos;
CheckMortPerMalos;
PintaPantalla;
CheckMapa;
until TeclaPuls(KeyESC) or (Pepe.vides<0);
GameOver;
until exit_game;
TancarVirtual(ptrpant1);
setmode(3);
desinstalarKB;
end.
Binary file not shown.
+75
View File
@@ -0,0 +1,75 @@
PEPE RUNNER v1.0 per al ASCII TOURNAMENT
© 21/10/00 Jaildesigner - Icekas
_____________________________________________________________
| |
| 1.- HISTORIA |
| |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Inspirat en el clàssic dels 80, LODE RUNNER, apareix la versió
ASCII-JAULERA d'aquell joc: el PEPE RUNNER. En un intent de rescatar
aquell joc clàssic, he fet aquesta versió en ASCII. Espere que vos
agrade el joc. Com he tingut un poquet de pressa al fer-lo, posiblement
apareguen noves versions en un futur, amb bugs corregits, noves
features i tal volta DirectX...
_____________________________________________________________
| |
| 2.- OBJECTIU |
| |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Per als que no heu jugat mai, l'objectiu es agafar tots els
diners de la pantalla. Quan els tingueu tots, apareixerà una
escala que vos permetrà pujar al nivell superior. Aneu amb compte
ja que els enemics també poden pillar els dinerets. Si algun
enemic amb diners acaba mort per alguna raó, perdra els diners
que havia furtat i els deixarà allà on els va trobar.
_____________________________________________________________
| |
| 3.- COM JUGAR |
| |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Pepe pot fer forats en el piso. Aquests forats, es tornen a
omplir amb el pas del temps, i si hi ha algú en el forat quan
es reompli perd una vida. Pepe també pot pujar i baixar escales
i moures per les cordes per a pasar d'un lloc a un altre. Lamen-
tablement, els seus enemics també poden fer-ho.
_____________________________________________________________
| |
| 4.- TECLES |
| |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Les tecles son les següents:
Q - Amunt
A - Avall
O - Esquerra
P - Dreta
SPACE - Forat a la esquerra
M - Forat a la dreta
H - Pausa (hold)
ESC - Acaba la partida
_____________________________________________________________
| |
| 5.- BUGS I FUTURES AMPLIACIONS |
| |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
De moment, el unic bug que conec i que em fa perea llevar es
el que fa que els enemics s'estavellen contra les parets i es
maten.
Si algun dia torne a agafar el codi, millorare coses com
aquestes:
- Opció de definir les tecles.
- Moltes mes fases, amb passwords i amb final. (de moment fa loop)
- Resposta del teclat.
+9
View File
@@ -0,0 +1,9 @@
var
fich : file of byte;
begin
Assign(fich, 'codi.exe');
reset(fich);
Write('CODI.EXE = ',filesize(fich));
Close(fich);
end.
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
var
fich : file of byte;
begin
Assign(fich, 'codi.exe');
reset(fich);
Write('CODI.EXE = ',filesize(fich));
Close(fich);
end.
+112
View File
@@ -0,0 +1,112 @@
unit tipos;
interface
uses grafix;
const
{ numer de pantalles }
num_fases = 2;
{ estats }
normal = 0;
caent = 4;
pujar = $01;
baixar = $02;
esquerra = $10;
dreta = $20;
enganxat = 6;
{ codi ascii dels sprites }
escala = 205;
pedra = 219;
diners = 36;
buit = 0;
corda = 196;
bloc1 = 176; { son per al fade dels blocs }
bloc2 = 177;
bloc3 = 178;
{ color dels sprites }
color_escala = 7;
color_pedra = 6;
color_diners = 14;
color_buit = 0;
color_corda = 7;
bloc_out = 100; { temps que est… el bloc desaparegut }
num_malos = 3; { obvi... }
temps_IA = 30; { temps que tenen el mateix estat els malos }
{ utils editor i joc }
num_items = 5;
llista_items : ARRAY [0..num_items-1] of byte = (buit, pedra, escala, corda, diners);
color_items : ARRAY [0..num_items-1] of byte = (color_buit, color_pedra, color_escala, color_corda, color_diners);
type
_tresor = RECORD
posX, posY : byte;
OK : boolean;
end;
_pepe = RECORD
posX, posY, dibuix, color, vides : integer;
estat : byte;
end;
_bloc = RECORD
tipo : byte;
color : byte;
temps : integer;
end;
_malo = RECORD
posX, posY, dibuix, color, ID : integer;
carrega : _tresor;
estat : byte;
IAclock : byte;
end;
var
i,j,k : word; { per a bucles }
pepe : _pepe;
pant1 : word;
ptrpant1 : ptr_pantalla;
mapa : ARRAY [0..39,0..24] of _bloc;
malo : ARRAY [0..num_malos-1] of _malo;
diners_pantalla : word; { numero de diners que hi ha en la pantalla al comen‡ar }
score : word; { puntuacio de la partida }
hi_score : word; { maxima puntuacio }
nom_hi_score : string;
level : integer; { numero de pantalla actual }
clock : word; { contador per al joc }
paleta : tpaleta;
offset_mapa : longint;
exit_game : boolean;
implementation
begin
end.
+112
View File
@@ -0,0 +1,112 @@
unit tipos;
interface
uses grafix;
const
{ numer de pantalles }
num_fases = 10;
{ estats }
normal = 0;
caent = 4;
pujar = $01;
baixar = $02;
esquerra = $10;
dreta = $20;
enganxat = 6;
{ codi ascii dels sprites }
escala = 205;
pedra = 219;
diners = 36;
buit = 0;
corda = 196;
bloc1 = 176; { son per al fade dels blocs }
bloc2 = 177;
bloc3 = 178;
{ color dels sprites }
color_escala = 7;
color_pedra = 6;
color_diners = 14;
color_buit = 0;
color_corda = 7;
bloc_out = 100; { temps que est… el bloc desaparegut }
num_malos = 3; { obvi... }
temps_IA = 30; { temps que tenen el mateix estat els malos }
{ utils editor i joc }
num_items = 5;
llista_items : ARRAY [0..num_items-1] of byte = (buit, pedra, escala, corda, diners);
color_items : ARRAY [0..num_items-1] of byte = (color_buit, color_pedra, color_escala, color_corda, color_diners);
type
_tresor = RECORD
posX, posY : byte;
OK : boolean;
end;
_pepe = RECORD
posX, posY, dibuix, color, vides : integer;
estat : byte;
end;
_bloc = RECORD
tipo : byte;
color : byte;
temps : integer;
end;
_malo = RECORD
posX, posY, dibuix, color, ID : integer;
carrega : _tresor;
estat : byte;
IAclock : byte;
end;
var
i,j,k : word; { per a bucles }
pepe : _pepe;
pant1 : word;
ptrpant1 : ptr_pantalla;
mapa : ARRAY [0..39,0..24] of _bloc;
malo : ARRAY [0..num_malos-1] of _malo;
diners_pantalla : word; { numero de diners que hi ha en la pantalla al comen‡ar }
score : word; { puntuacio de la partida }
hi_score : word; { maxima puntuacio }
nom_hi_score : string;
level : integer; { numero de pantalla actual }
clock : word; { contador per al joc }
paleta : tpaleta;
offset_mapa : longint;
exit_game : boolean;
implementation
begin
end.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+150
View File
@@ -0,0 +1,150 @@
unit utext;
interface
uses grafix;
procedure PutSprite(posX, posY, color, lletra : word);
{ Funci¢: Coloca un caracter en pantalla }
procedure PutString(posX, posY, color : word; frase : string);
{ Funci¢: Coloca una frase en pantalla }
procedure PutStringCENTERED(posY, color : word; frase : string);
{ Funci¢: Coloca una frase en pantalla i centrada horitzontalment }
procedure PutStringWINDOWED(posY, color : word; frase : string);
{ Funci¢: Coloca una frase dins d'una finestra centrada }
procedure cls(pant : word);
{ Funci¢: Borra la pantalla }
procedure PintaPantalla;
{ Funci¢: Pinta la pantalla }
procedure SetupVirtualText(var screen:ptr_pantalla;var virtual_addr:word);
{ Funci¢: Crea una pantalla virtual de text (2K) }
procedure TancarVirtualText(var screen:ptr_pantalla);
{ Funci¢: Tanca la pantalla virtual de text (2k) }
procedure HideCursor;
procedure ShowCursor;
implementation
uses crt, tipos;
{##############################################################}
procedure SetupVirtualText(var screen:ptr_pantalla;var virtual_addr:word);
begin
getmem(screen,2000);
virtual_addr:=seg(screen^);
end;
{##############################################################}
procedure TancarVirtualText(var screen:ptr_pantalla);
begin
freemem(screen,2000);
end;
{##############################################################}
procedure PutSprite(posX, posY, color, lletra : word);
var i : word;
begin
mem[$B800:((posX) shl 1)+(posY*80)]:=lletra;
mem[$B800:((posX) shl 1)+1+(posY*80)]:=color;
end;
{##############################################################}
procedure PutString(posX, posY, color : word; frase : string);
var i : word;
begin
for i:=0 to LENGTH(frase)-1 do
begin
mem[$B800:((i+posX) shl 1)+(posY*80)]:=ord(frase[i+1]);
mem[$B800:((i+posX) shl 1)+1+(posY*80)]:=color;
end;
end;
{##############################################################}
procedure PutStringCENTERED(posY, color : word; frase : string);
var i : word;
ini : word;
begin
ini := (40 - LENGTH(frase)) div 2;
for i:=0 to LENGTH(frase)-1 do
begin
mem[$B800:((i+ini) shl 1)+(posY*80)]:=ord(frase[i+1]);
mem[$B800:((i+ini) shl 1)+1+(posY*80)]:=color;
end;
end;
{##############################################################}
procedure PutStringWINDOWED(posY, color : word; frase : string);
var i : word;
ini : word;
ample : word;
begin
ini := (40 - LENGTH(frase)) div 2;
ample := LENGTH(frase) + 4;
for i:=0 to LENGTH(frase)-1 do
begin
mem[$B800:((i+ini) shl 1)+(posY*80)]:=ord(frase[i+1]);
mem[$B800:((i+ini) shl 1)+1+(posY*80)]:=color;
end;
for i:=0 to LENGTH(frase)+3 do
begin
mem[$B800:((i+ini-2) shl 1)+((posY-1)*80)]:=196;
mem[$B800:((i+ini-2) shl 1)+1+((posY-1)*80)]:=color;
mem[$B800:((i+ini-2) shl 1)+((posY+1)*80)]:=196;
mem[$B800:((i+ini-2) shl 1)+1+((posY+1)*80)]:=color;
end;
end;
{##############################################################}
procedure cls(pant : word);
var i : word;
begin
for i:=0 to 1999 do mem[pant:i]:=0;
end;
{##############################################################}
procedure PintaPantalla;
var i,j : word;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
{ pepe }
mem[pant1:((pepe.posX) shl 1)+(pepe.posY*80)]:=pepe.dibuix;
mem[pant1:((pepe.posX) shl 1)+(pepe.posY*80)+1]:=pepe.color;
{ malos }
mem[pant1:((malo[0].posX) shl 1)+(malo[0].posY*80)]:=malo[0].dibuix;
mem[pant1:((malo[0].posX) shl 1)+(malo[0].posY*80)+1]:=malo[0].color;
mem[pant1:((malo[1].posX) shl 1)+(malo[1].posY*80)]:=malo[1].dibuix;
mem[pant1:((malo[1].posX) shl 1)+(malo[1].posY*80)+1]:=malo[1].color;
mem[pant1:((malo[2].posX) shl 1)+(malo[2].posY*80)]:=malo[2].dibuix;
mem[pant1:((malo[2].posX) shl 1)+(malo[2].posY*80)+1]:=malo[2].color;
espera_VGA;espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(14,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
inc(clock);
end;
{##############################################################}
procedure HideCursor;assembler;
asm
mov ax,0100h
mov cx,0100h
int 10h
end;
{##############################################################}
procedure ShowCursor;assembler;
asm
mov ax,0100h
mov cx,0607h
int 10h
end;
{##############################################################}
begin
end.
+150
View File
@@ -0,0 +1,150 @@
unit utext;
interface
uses grafix;
procedure PutSprite(posX, posY, color, lletra : word);
{ Funci¢: Coloca un caracter en pantalla }
procedure PutString(posX, posY, color : word; frase : string);
{ Funci¢: Coloca una frase en pantalla }
procedure PutStringCENTERED(posY, color : word; frase : string);
{ Funci¢: Coloca una frase en pantalla i centrada horitzontalment }
procedure PutStringWINDOWED(posY, color : word; frase : string);
{ Funci¢: Coloca una frase dins d'una finestra centrada }
procedure cls(pant : word);
{ Funci¢: Borra la pantalla }
procedure PintaPantalla;
{ Funci¢: Pinta la pantalla }
procedure SetupVirtualText(var screen:ptr_pantalla;var virtual_addr:word);
{ Funci¢: Crea una pantalla virtual de text (2K) }
procedure TancarVirtualText(var screen:ptr_pantalla);
{ Funci¢: Tanca la pantalla virtual de text (2k) }
procedure HideCursor;
procedure ShowCursor;
implementation
uses crt, tipos;
{##############################################################}
procedure SetupVirtualText(var screen:ptr_pantalla;var virtual_addr:word);
begin
getmem(screen,2000);
virtual_addr:=seg(screen^);
end;
{##############################################################}
procedure TancarVirtualText(var screen:ptr_pantalla);
begin
freemem(screen,2000);
end;
{##############################################################}
procedure PutSprite(posX, posY, color, lletra : word);
var i : word;
begin
mem[$B800:((posX) shl 1)+(posY*80)]:=lletra;
mem[$B800:((posX) shl 1)+1+(posY*80)]:=color;
end;
{##############################################################}
procedure PutString(posX, posY, color : word; frase : string);
var i : word;
begin
for i:=0 to LENGTH(frase)-1 do
begin
mem[$B800:((i+posX) shl 1)+(posY*80)]:=ord(frase[i+1]);
mem[$B800:((i+posX) shl 1)+1+(posY*80)]:=color;
end;
end;
{##############################################################}
procedure PutStringCENTERED(posY, color : word; frase : string);
var i : word;
ini : word;
begin
ini := (40 - LENGTH(frase)) div 2;
for i:=0 to LENGTH(frase)-1 do
begin
mem[$B800:((i+ini) shl 1)+(posY*80)]:=ord(frase[i+1]);
mem[$B800:((i+ini) shl 1)+1+(posY*80)]:=color;
end;
end;
{##############################################################}
procedure PutStringWINDOWED(posY, color : word; frase : string);
var i : word;
ini : word;
ample : word;
begin
ini := (40 - LENGTH(frase)) div 2;
ample := LENGTH(frase) + 4;
for i:=0 to LENGTH(frase)-1 do
begin
mem[$B800:((i+ini) shl 1)+(posY*80)]:=ord(frase[i+1]);
mem[$B800:((i+ini) shl 1)+1+(posY*80)]:=color;
end;
for i:=0 to LENGTH(frase)+3 do
begin
mem[$B800:((i+ini-2) shl 1)+((posY-1)*80)]:=196;
mem[$B800:((i+ini-2) shl 1)+1+((posY-1)*80)]:=color;
mem[$B800:((i+ini-2) shl 1)+((posY+1)*80)]:=196;
mem[$B800:((i+ini-2) shl 1)+1+((posY+1)*80)]:=color;
end;
end;
{##############################################################}
procedure cls(pant : word);
var i : word;
begin
for i:=0 to 1999 do mem[pant:i]:=0;
end;
{##############################################################}
procedure PintaPantalla;
var i,j : word;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
{ pepe }
mem[pant1:((pepe.posX) shl 1)+(pepe.posY*80)]:=pepe.dibuix;
mem[pant1:((pepe.posX) shl 1)+(pepe.posY*80)+1]:=pepe.color;
{ malos }
mem[pant1:((malo[0].posX) shl 1)+(malo[0].posY*80)]:=malo[0].dibuix;
mem[pant1:((malo[0].posX) shl 1)+(malo[0].posY*80)+1]:=malo[0].color;
mem[pant1:((malo[1].posX) shl 1)+(malo[1].posY*80)]:=malo[1].dibuix;
mem[pant1:((malo[1].posX) shl 1)+(malo[1].posY*80)+1]:=malo[1].color;
mem[pant1:((malo[2].posX) shl 1)+(malo[2].posY*80)]:=malo[2].dibuix;
mem[pant1:((malo[2].posX) shl 1)+(malo[2].posY*80)+1]:=malo[2].color;
espera_VGA;espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(13,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
inc(clock);
end;
{##############################################################}
procedure HideCursor;assembler;
asm
mov ax,0100h
mov cx,0100h
int 10h
end;
{##############################################################}
procedure ShowCursor;assembler;
asm
mov ax,0100h
mov cx,0607h
int 10h
end;
{##############################################################}
begin
end.
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
append.exe
fusio.exe
Binary file not shown.