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:
 
Gebaeude
Die Gebäude- und Boden-/Untergrund-Tiles.
 
Schrift
 Die Fonts (der Schriftsatz).

Fahrzeuge 1
Fahrzeug-Tiles.
 
Fahrzeuge 2
Weitere Fahrzeug-Tiles.
 
 
Pilz, ich hoffe du kannst dich noch daran erinnern. Es waren herrliche Zeiten.
2 Kommentare, Ideen, Vorschläge
1
06. November 2011  |  Yves
Schönes ding habt ihr komplet alles in assember programmiert?
2
06. November 2011  |  Matthias Sonnenkalb
Nein, nur die Stellen, bei denen es auf eine schnelle Verarbeitung ankam bzw. diejenigen, bei denen wir einfach Spaß hatten, so systemnah wie möglich zu programmieren :-)
Der größte Teil wurde natürlich in C programmiert.
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:
[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