Aus längst vergangenen Zeiten
05. November 2011
| aktualisiert am 05. November 2011
Ein kleiner Mitschnitt eines alten Projekts, an dem der Pilz und ich einige Wochenenden vor Weihnachten '95 programmiert hatten. Tja, das ist nun schon über 15 Jahre her. Unglücklicherweise haben wir uns dann Anfang '96 nicht wieder zusammengefunden, um weiter an dem Projekt zu arbeiten. Warum eigentlich nicht? Hm, das weiß von uns beiden heute Keiner mehr. Naja, jedenfalls hatte ich den Quellcode und das "Spiel" vor kurzem wieder in meiner Sammlung alter Projekte gefunden und es läuft tatsächlich noch im XP-Modus. Man kann z.B. einen Panzer (der vier gegnerischen Teams) anklicken und damit ein Fahrzeug eines anderen Teams angreifen und zerstören. Man konnte auch Gebäude bauen (die schon da waren??? Naja, egal). Die Fahrzeuge fuhren schon selbständig mit einer mehr oder weniger intelligenten KI. Achso, das Knacken, das ihr vielleicht hören könnt, bedeutet nicht, dass euere Boxen kaputt sind, es ist der PC-Speaker, der die Schussgeräusche der Panzer ausgibt :-)
Besonders cool war es auch, unseren alten Assemblercode mal wieder zu sehen. Hier ein kleiner Auszug:
; Modul zum Einbinden in G00.CPP
;*SUCHSTRINGS************************************************************
; !!! = Achtung mögliche Fehlerquelle
; ??? = Programmteil noch nicht fertig
; %%% = Entwicklungshilfe , kann später entfernt werden
; !noK = Konstanten wurden nicht verwendet
;*KONSTANTEN**EXTERN DEKLARATIONEN***************************************
INCLUDE G10EXCO.INC
;************************************************************************
.model large,c
.386
RestMou PROTO C
SavMou PROTO C
.data
MouSeg WORD 0abefh
WORD 0abf4h
OldOfs WORD ?
WORD ?
BldSeg WORD 0a000h
FldSeg WORD 0a3e8h
WriteMode0 WORD ?
WriteMode1 WORD ?
S spr_struct SPRITE_NUM DUP ({?})
public S
Cat cat_struct CAT_NUM DUP ({0})
public Cat
S2_0_A spr2_struct1 {?}
S2_0_B spr2_struct2 SPR2_NUM0 DUP ({?})
S2_1_A spr2_struct1 {?}
S2_1_B spr2_struct2 SPR2_NUM1 DUP ({?})
S2_2_A spr2_struct1 {?}
S2_2_B spr2_struct2 SPR2_NUM2 DUP ({?})
S2_3_A spr2_struct1 {?}
S2_3_B spr2_struct2 SPR2_NUM3 DUP ({?})
public S2_0_A
public S2_0_B
public S2_1_A
public S2_1_B
public S2_2_A
public S2_2_B
public S2_3_A
public S2_3_B
Spr2Poi NPVOID S2_0_A
NPVOID S2_1_A
NPVOID S2_2_A
NPVOID S2_3_A
.code
;***************************************************************************
SegInit proc
mov ax,ds ; FS = DS ( Datensegment alternativ über
mov fs,ax ; FS erreichbar )
ret
SegInit endp
;***************************************************************************
InitLin proc uses di
mov ax,0013h
int 10h
mov dx,3ceh ; auftrennen der Speicheradressen
mov al,5 ; im Graphics_Mode_reg. des Graphic_Ctrl.
out dx,al ; über 'and' abschalten (Bit 4 -> 0)
inc dx ; auf des Datenreg.des Graph._Ctrl (3cfh)
; erhöhen
in al,dx ; Vorhandene Daten von 3cfh lesen
and al,11101111b ; hier Bit 4 des Grafik_Mode_Reg.löschen
out dx,al
;** Variablen für Write Modi laden
mov ah,al ; AH = Daten
mov al,5 ; AL = Registernummer
mov WriteMode0,ax ; für Mode 0 laden
and ah,not 3 ; Bits für Write Mode löschen
or ah,1 ; Bit für Mode 1 setzen
mov WriteMode1,ax ; für Mode 1 laden
;**
dec dx ; dx wieder auf 3ceh (Portadr.des Graf.Ctrl)
mov al,6 ; das Ganze nochmal im Micellaneous_REg.
out dx,al ; über Bit #1
inc dx
in al,dx
and al,11111101b
out dx,al
mov dx,3c4h ; das Memory-Mode-REg.im Sequencer-Ctrl.
mov al,4 ; dahingehend modifizieren, dass keine Auf-
out dx,al ; der Adressen in den Bitplanes erfolgt
inc dx ; und die aktuelle Bitplane festlegen
in al,dx ; über das Bit-Mask-Reg.
and al,11110111b
or al,4
out dx,al
mov ax,0a000h ; alle vier Bitplanes komplett mit
mov es,ax ; mit dem Farbcode 0h füllen und
xor di,di ; damit den Bildschirm löschen
mov ax,di
mov cx,8000h
rep stosw
mov dx,3d4h ; Doppelwort-Modus über das Bit 6
mov al,14h ; im Underline-Register des CRT-Ctrl.deakt.
out dx,al
inc dx
in al,dx
and al,10111111b
out dx,al
dec dx
mov al,17h ; über Bit 6 im Mode-Control-Reg. des
out dx,al ; CRT-Ctrl. jetzt vom Word- in den Byte-
inc dx ; Modus wechseln
in al,dx
or al,01000000b
out dx,al
mov ah,SCREENX/8 ; Anzahl der Offsets pro Zeile
mov al,13h ; Nummer des Offsetregisters
dec dx ; Adresse des Video-Controllers
out dx,ax
mov dx,3ceh ; Write Mode 0 ist Standard
mov ax,WriteMode0
out dx,ax
ret
InitLin endp
;***************************************************************************
DacSet proc uses es \
arg1 : word ; Offset
mov ax,1012h ;** Gruppe DAC_register setzen
mov bx,ds ; ES = Segmentadresse
mov es,bx
xor bx,bx ; Erstes DAC_Register
mov cx,100h ; Anzahl der DAC_Register
mov dx,arg1 ; Offset DAC-Register
int 10h
ret
DacSet endp
;** DACs (16-255) für BGR einblenden ***************************************
DacOn proc uses es di si \
arg1 : word , arg2 : word
local buf[768] : byte , buf1[768] : byte
; arg1 = Dateihandle
; arg2 = Zeit
push ds ; DS = SS
mov ax,ss
mov ds,ax
mov ah,3fh ; Funktion Datei lesen
lea dx,buf ; DX = Offset buf
mov cx,768 ; CX = zu lesende Bytes
int 21h ; Datei lesen
mov si,64 ; große Schreife: 64* DACs ändern
dac0:
dec si
mov di,768 ; kleine Schleife: DAC 0-255 ändern (3*268)
dac1:
dec di
mov al,buf[di] ; AL = Originalwert
and al,00111111b ; unzulässige Bits ausblenden
; shr al,2
xor ah,ah ; AL -= gr. Schleifenz. (63 -> 0)
sub ax,si ;
test ax,8000h ; IF (AX==negativ) AL = 0
je @F ;
mov al,0 ;
@@: ;
mov buf1[di],al ; AL in Puffer
or di,di
jne dac1 ; Ende kleine Schleife
mov cx,arg2 ; Warteschleife
w: RETRACE ; auf vertikalen Rücklauf warten
loop w
mov ax,1012h ;* Gruppe DAC_register setzen
mov bx,ds ; ES = Segmentadresse
mov es,bx
lea dx,buf1 ; Offset DAC-Register
mov bx,0 ; Erstes DAC_Register
mov cx,256 ; Anzahl der DAC_Register
int 10h
or si,si
jne dac0 ; Ende große Schleife
pop ds
ret
DacOn endp
...
Hier noch ein paar Screenshots einiger unserer Sprites und Entwürfe, die wir liebevoll mit Paintbrush erstellt hatten:

Die Gebäude- und Boden-/Untergrund-Tiles.

Die Fonts (der Schriftsatz).

Fahrzeug-Tiles.

Weitere Fahrzeug-Tiles.
Pilz, ich hoffe du kannst dich noch daran erinnern. Es waren herrliche Zeiten.
2 Kommentare bisher.
HILFE
Code-Beispiele werden mit den BBCodes [code][/code] dargestellt.
Jedes Tag muss eine Zeile für sich allein haben, d.h der Beispiel-Code
muss wirklich ZWISCHEN den Tags stehen. Beispiel:
Alles was zwischen den beiden Tags [register] und [/register] eingetragen wird, ist nur für registrierte (und eingeloggte) User sichtbar.
[code] ACHTUNG! HIER UMBRUCH WICHTIG. TAG [code] MUSS ALLEIN STEHEN
#include <stdio.h>
int main( void ){
return 0;
} ACHTUNG! HIER UMBRUCH WICHTIG. NACHFOLGENDES TAG [/code] MUSS ALLEIN STEHEN
[/code]Alles was zwischen den beiden Tags [register] und [/register] eingetragen wird, ist nur für registrierte (und eingeloggte) User sichtbar.
Dein Name *
Deine Email
Deine Website
Vorschau
Der größte Teil wurde natürlich in C programmiert.