< Poprzedni rozdział | Następny rozdział >
Niniejszy dokument będzie poświęcony zagadnieniom realizacji punktu I planu ramowego. Plansza złożona jest z pól. Jest to prostokątna struktura złożona z pól. Dla szybkości obliczeń szerokośc mapy (oraz wysokość) będą potęgami liczby 2. Każde pole będzie 64-bitowe i będzie zawierało wszelakie informacje o statusie pól, jak rodzaj kafla, obecność melanżu na pustyni, powiązana struktura (budynek), bądź stacjonujaca jednostka. Poza tym pole będzie przechowywało status mgły wojny.
Struktura pola będzie tworzona dynamicznie. Na razie wiadomo ile ona zajmuje, czyli dwa długie słowa. Pomieścimy tu wszystkie niezbędne informacje. Niech dane będą podzielone na 16-bitowe części. Oto zapis bitowy i legenda:
%---rodzaj kafla-- -rodzaj nakładki- -powiązany obiekt- ------flagi------
Zanim przejdziemy do sedna sprawy, warto przygotować rozsądne środowisko pracy. Na początku program musi pobrać wiadomość od Workbencha, celem pobrania parametrów programu oraz umożliwienia używania operacji biblioteki DOS przez nasz program.
Program będę pisał w asemblerze, ale uprzednio tworząc pseudokod podobny do języka C lub Pascal. Pseudokod ma na celu przygotowanie do pisania danej funkcji oraz uodpornienia jej na błędy, które często zdarzają się w programach pisanych w asemblerze.
Zatem szkielet kodu startowego/zamykającego będzie następujący:
;program Diuna ;begin ; a1 := NULL; ; d0 := FindTask(); (* Pobierz strukturę Task/Process *) ; a0 := d0 ; a0 := &( a0->pr_MsgPort ); (* Załaduj adres portu procesu *) ; ; if( ( d2 := d0 := GetMsg() ) <> NULL ) begin (* Pobierz wiadomość Workbencha *) ; a0 := d0; ; get_tooltypes(); (* Pobierz parametry *) ; end; ; ; program(); (* Wywołanie programu *) ; ; if( d2 <> NULL ) begin ; Forbid(); ; a1 := d2; ; ReplyMsg(); (* Zwróc wiadomość Workbencha *) ; end; ;end.
W asemblerze:
start: suba.l a1,a1 CallExec FindTask ; Pobierz Process movea.l d0,a0 lea pr_MsgPort(a0),a0 CallExec GetMsg ; Pobierz WBStartup move.l d0,d2 beq.s .no_wb movea.l d0,a0 bsr.s get_tooltypes ; Pobierz ToolTypes .no_wb: bsr.s program ; Wykonaj program główny tst.l d2 beq.s .no_wb2 CallExec Forbid() movea.l d2,a1 CallExec ReplyMsg ; Zwróć WBStartup .no_wb2: moveq #0,d0 ; Gotowe rts
Jaki będzie szkielet programu głównego? Warto zastanowić się chwilę. Najpierw należy przygotować środowisko wejścia/wyjścia. Póki co zastosujemy konsolę do tego celu, ale oczywiście docelowo będzie to osobny ekran oraz kontrola za pomocą myszy i klawiatury.
Stwórzmy funkcję InitIO, która zainicjuje to środowisko:
;procedure InitIO ; a1 := &( intuiname ); ; d0 := 39; ; if( intuibase := d0 := OpenLibrary() ) begin ; a0 := &( nw ); ; if( window := d0 := OpenWindow() ) begin ; if( conmp := d0 := CreateMsgPort() ) begin ; a0 := d0; ; d0 := IOSTD_SIZE; ; if( conio := d0 := CreateIORequest() ) begin ; a1 := d0; ; a1->io_Data := window; ; a1->io_Length := Window_SIZEOF; ; a0 := &( conname ); ; d0 := CONU_SNIPMAP; ; d1 := 0; ; if( ( d0 := OpenDevice() ) == 0 ) begin ; return 0; ; a0 := conio; ; DeleteIORequest(); ; end; ; a0 := conmp; ; DeleteMsgPort(); ; end; ; a0 := window; ; CloseWindow(); ; end; ; a1 := intuibase; ; CloseLibrary(); ; end ; return -1; ;end;
initio: lea intuiname(pc),a1 moveq #39,d0 CallExec OpenLibrary move.l d0,intuibase beq.s .nointui lea newwindow(pc),a0 CallIntui OpenWindow move.l d0,window beq.s .nowindow CallExec CreateMsgPort move.l d0,conmp beq.s .noconmp movea.l d0,a0 move.l #IOSTD_SIZE,d0 CallExec CreateIORequest move.l d0,conio beq.s .noconio movea.l d0,a1 move.l window(pc),io_Data(a1) move.l #Window_SIZEOF,io_Length(a1) lea conname(pc),a0 move.l #CONU_SNIPMAP,d0 clr.l d1 CallExec OpenDevice tst.l d0 bne.s .nocon rts .nocon: movea.l conio(pc),a0 CallExec DeleteIORequest .nooconio: movea.l conmp(pc),a0 CallExec DeleteMsgPort .noconmp: movea.l window(pc),a0 CallIntui CloseWindow .nowindow: movea.l intuibase(pc),a1 CallExec CloseLibrary .nointui: moveq #-1,d0 rts newwindow: dc.w 0, 56, 640, 200 dc.b 0, 1 dc.l IDCMP_CLOSEWINDOW dc.l WFLG_CLOSEGADGET!WFLG_DRAGBAR!WFLG_DEPTHGADGET!WFLG_SIMPLE_REFRESH!WFLG_NOCAREREFRESH dc.l 0 dc.l 0 dc.l title dc.l 0 dc.l 0 dc.w 0, 0, ~0, ~0 dc.w WBENCHSCREEN
Autor strony: Robert Szacki, Ostatnia modyfikacja artykułu: 05.04.2017