ccz80

Would you like to react to this message? Create an account in a few clicks or log in to continue.
ccz80

ccz80 programming language


3 posters

    3D-Maze game for Amstrad CPC

    avatar
    poppichicken


    Posts : 37
    Join date : 2009-10-09

    3D-Maze game for Amstrad CPC Empty 3D-Maze game for Amstrad CPC

    Post  poppichicken Fri Dec 11, 2009 4:39 pm

    Hi all.

    I've finally finished my conversion of an old BASIC program to ccz80 and assembler.
    I've converted a type-in game from Amstrad Computer User, October 1985.
    It is the 3D-Maze game by Nigel Sharp.

    I've wanted to create an Amstrad machine code program for 24 years.
    I really liked this game when I was a child, and I thought converting it would be a good way to learn machine code.
    ccz80 has made the process MUCH easier.

    The code isn't very nice. In fact it's probably quite hard to follow in places.
    And I haven't commented it very much unfortunately.
    But it works, and is MANY MANY times faster than the BASIC original.
    In addition to the huge increase in speed, I was able to figure out how to make the display double-buffered, so there is no flickering during the screen redraw.

    During the conversion, I discovered just how slow the ROM draw routines are. They are very good, and very flexible, but so slow...
    So I wrote new routines to draw the lines, based on the fast plotting routines I found on cpcwiki.
    I was able to speed them up further due to the fact that I didn't need a general line drawing routine.
    All the lines are either vertical, horizontal, or a perfect 45 degree diagonal.
    This meant that I could take several shortcuts when calculating the memory addresses of pixels in a line.

    I've attached the code, and the dsk image can be downloaded from here:
    http://www.cpcwiki.eu/imgs/f/f1/3d-maze.zip

    To compile the code, I used the following command-line statement:
    ccz80 3d-maze.ccz80 /org=#8000

    To write the compiled binary file to a dsk image, I used the following code inside WinAPE's assembler:
    write direct "a:3d-maze.bin"
    org &8000
    incbin "c:\ccz80\3d-maze.bin"


    Enjoy!

    Code:

    include "cpc6128.ccz80";

    byte dir;
    byte en;
    byte d;
    byte ky;
    byte dtt;
    byte sn;
    byte flash=0;
    byte wfc,place;

    word a;
    word moves;
    word mx,my;
    word lev,levOffset;
    word x,y;
    word otx,oty;
    word tx,ty;
    word targX,targY;

    word tmp1,tmp2,tmp20;
    byte tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,tmp10,tmp11,tmp12,tmp13,tmp14,tmp15,tmp16,tmp17,tmp18,tmp19,tmp21;

    array byte clock[4];
    array byte text[21];
    array byte sLeft={0,30,51,66,76,83,88,92,94,96,97,98};
    array byte sRight={199,169,148,133,123,116,111,107,105,103,102,101};

    array byte entSections1={130,5,255,1,10,1,1}; // 2 sections with 3 bytes each. The section number has had 128 added, as the env number is to be treated as negative.
    array byte entSections2={129,1,15,1}; // 1 section with 3 bytes. The section number has had 128 added, as the env number is to be treated as negative.
    array byte envSections1={1,5,255,1,100,0,100};
    array byte envSections2={2,15,255,1};

    array byte symbol_buffer[8]; // (256-255)*8=8
    array byte symbol_arrowUp={24,60,126,255,24,24,24,24};
    array byte symbol_arrowDown={24,24,24,24,255,126,60,24};
    array byte symbol_arrowLeft={16,48,112,255,255,112,48,16};
    array byte symbol_arrowRight={8,12,14,255,255,14,12,8};

    array byte endSoundNote={119,119,119,119,95,95,95,95,80,80,80,60};
    array byte endSoundLen={20,10,10,20,20,10,10,20,20,20,20,60};
    array byte levSoundVol={0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8};

    symbolafter(255,symbol_buffer);

    array byte hiTable[315]; // 15 elements of 21 bytes each.
    array word hiScore[15];
    word hsc1,hsc2;

    array byte ma={
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,
    1,0,1,1,1,0,1,0,1,0,1,1,1,1,0,1,1,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,
    1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,
    1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,0,1,0,1,0,1,
    1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,0,0,1,
    1,0,1,0,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,
    1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,
    1,0,1,0,1,0,1,0,1,0,1,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,1,
    1,0,1,1,1,1,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,1,
    1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,1,
    1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0,1,
    1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,1,0,1,
    1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,
    1,0,1,0,0,0,1,0,1,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,0,1,
    1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,
    1,0,1,0,0,0,1,0,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,1,
    1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,
    1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,
    1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,
    1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,
    1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,
    1,0,1,0,0,0,1,0,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,1,
    1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,
    1,0,1,0,0,0,1,0,1,1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,0,1,
    1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,
    1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,1,
    1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1,1,0,1,
    1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,1,1,1,0,0,0,1,0,1,1,0,1,0,0,1,
    1,1,1,1,1,0,0,0,1,0,1,0,1,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,1,1,
    1,0,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,1,0,1,1,0,0,0,0,1,
    1,0,1,0,0,0,1,1,0,0,1,1,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,0,0,1,0,1,1,0,1,
    1,0,1,1,1,0,1,0,0,1,1,0,1,0,0,0,1,1,0,0,0,1,0,0,1,1,0,1,0,1,0,0,0,1,1,
    1,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1,1,1,0,0,1,
    1,0,1,1,1,1,0,0,1,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,1,
    1,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,0,1,
    1,1,1,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,1,0,1,0,1,
    1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,
    1,0,1,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0,1,1,1,0,1,
    1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,1,1,1,0,1,1,1,0,0,0,0,0,1,0,1,0,1,0,1,
    1,0,1,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,1,0,1,0,0,0,1,
    1,0,0,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,0,0,1,0,0,0,1,0,1,0,1,1,1,
    1,1,1,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,
    1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,0,1,0,1,
    1,0,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,
    1,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,0,1,0,1,1,
    1,0,1,1,1,0,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,1,0,1,0,0,1,1,0,1,0,0,1,
    1,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,1,0,1,
    1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,0,1,1,0,0,0,1,0,1,0,0,1,
    1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
    };

    array byte view={
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    };

    srand(**time(clock));
    printc(22);
    printc(0);
    printc(23);
    printc(0);

    ent(1,entSections1);
    ent(2,entSections2);
    env(1,envSections1);
    env(2,envSections2);

    for (a=0;a<=14;a++)
    {
      **(hiScore+(a*2))=(a+1)*100;
      strcpy(hiTable+(a*21),"Nobody in particular");
    }

    asm{"ld iyl,0"}

    s230:
    asm
    {
    "ld hl,#0a01","call __km_set_delay",
    "ld a,1","call __scr_set_mode",

    "xor a","ld bc,#0000","call __scr_set_ink",
    "ld a,1","ld bc,#1a1a","call __scr_set_ink",
    "ld a,2","ld bc,#0c0c","call __scr_set_ink",
    "ld a,3","ld bc,#0e0e","call __scr_set_ink",

    "ld bc,#0b0b","call __scr_set_border",
    "ld a,1","call __txt_set_pen",
    "xor a","call __txt_set_paper",
    "ld hl,#0101","call __txt_set_cursor"
    }

    prints("3-D Maze");

    asm
    {
    "ld hl,#0102","call __txt_set_cursor",
    "call print2",
    "ld a,2","call __txt_set_pen",
    "ld hl,#0103","call __txt_set_cursor"
    }

    prints("Original by Nigel Sharp (1985)\r\nccz80 version by Ervin Pajor (2009)\r\n\r\n");
    asm{"ld a,3","call __txt_set_pen"}
    prints("Work your way down through the four\r\nlevels of the maze to the ground\r\nfloor, where you must find the target\r\nmarked with a blue cross.\r\n\r\nOn each level there is a hole leading\r\nto the next level.\r\n\r\nThere are several things to help you.\r\n\r\nMost useful is the map, which is built\r\nup as you explore.\r\n\r\nThe hole/target is shown as a black\r\ndot, and your current position is\r\nshown flashing.\r\n\r\nTurn: LEFT & RIGHT CURSOR KEYS\r\nMove: COPY KEY");

    asm
    {
    "ld hl,#1e19","call __txt_set_cursor",
    "ld a,1","call __txt_set_paper",
    "ld a,2","call __txt_set_pen"
    }

    prints("PRESS A KEY");
    clearinput();
    while (!inkey());

    moves=0;
    lev=0;

    asm
    {
    "ld a,2","call __gra_set_pen",
    "ld a,1","call __scr_set_mode",
    "ld bc,#0202","call __scr_set_border",

    "xor a","ld bc,#0000","call __scr_set_ink",
    "ld a,1","ld bc,#0e0e","call __scr_set_ink",
    "ld a,2","ld bc,#0c0c","call __scr_set_ink",
    "ld a,3","ld bc,#0303","call __scr_set_ink",

    "ld a,1","call __txt_str_select",
    "ld hl,#1900","ld de,#2718","call __txt_win_enable",

    "ld a,3","call __txt_set_paper",
    "call __txt_clear_window",
    "xor a","call __txt_set_pen",
    "ld hl,#0302","call __txt_set_cursor"
    }

    prints("3-D Maze");

    asm
    {
    "ld hl,#0303","call __txt_set_cursor",
    "call print2",
    "ld a,1","call __txt_set_pen",
    "ld hl,#0305","call __txt_set_cursor"
    }

    prints("Level:");
    asm{"ld hl,#0307","call __txt_set_cursor"}
    prints("Moves taken");
    asm{"ld hl,#0308","call __txt_set_cursor"}
    prints("so far:");
    asm{"ld hl,#030a","call __txt_set_cursor"}
    prints("Moves to");
    asm{"ld hl,#030b","call __txt_set_cursor"}
    prints("target:");

    asm
    {
    "ld hl,#080e","call __txt_set_cursor",
    "ld a,78","call __txt_output",
    "ld hl,#0a10","call __txt_set_cursor",
    "ld a,69","call __txt_output",
    "ld hl,#0812","call __txt_set_cursor",
    "ld a,83","call __txt_output",
    "ld hl,#0610","call __txt_set_cursor",
    "ld a,87","call __txt_output",
    "ld a,2","call __txt_set_paper",

    "ld a,iyl","cp 1","jp c,copy4000",
    "ld de,#c000","ld hl,#4000",
    "jp performCopy",

    "copy4000:",
    "ld de,#4000","ld hl,#c000",

    "performCopy:",
    "ld bc,#4000","ldir"
    }

    s870:
    dir=(rand()%4)+1;

    lev++;
    levOffset=(lev-1)*525; // level*rows*columns = level*15*35 = level*525

    mx=520;
    my=48;

    asm
    {
    "ld a,2","call __txt_set_pen",
    "ld a,3","call __txt_set_paper",
    "ld hl,#0a05","call __txt_set_cursor"
    }

    prints(strltrm(btoa(text,lev),48));

    asm
    {
    "call virtualFlip",
    "ld hl,#0a05","call __txt_set_cursor"
    }

    prints(strltrm(btoa(text,lev),48));

    asm
    {
    "ld hl,#080f","call __txt_set_cursor",
    "ld a,32","call __txt_output",
    "ld hl,#0910","call __txt_set_cursor",
    "ld a,32","call __txt_output",
    "ld hl,#0811","call __txt_set_cursor",
    "ld a,32","call __txt_output",
    "ld hl,#0710","call __txt_set_cursor",
    "ld a,32","call __txt_output"
    }

    for (a=21;a<=24;a++)
    {
      asm
      {
      "ld h,4","ld a,(_a)","ld l,a","call __txt_set_cursor",
      "call print3"
      }
    }

    asm
    {
    "call virtualFlip",
    "ld hl,#080f","call __txt_set_cursor",
    "ld a,32","call __txt_output",
    "ld hl,#0910","call __txt_set_cursor",
    "ld a,32","call __txt_output",
    "ld hl,#0811","call __txt_set_cursor",
    "ld a,32","call __txt_output",
    "ld hl,#0710","call __txt_set_cursor",
    "ld a,32","call __txt_output"
    }

    for (a=21;a<=24;a++)
    {
      asm
      {
      "ld h,4","ld a,(_a)","ld l,a","call __txt_set_cursor",
      "call print3"
      }
    }

    s880:
    x=(rand()%33)+2;
    y=(rand()%13)+2;

    otx=x;
    oty=y;

    if (lev==1)
    {
      otx=1;
      oty=1;
    }

    if (*(ma+levOffset+(y*35)+x-36)==1) goto s880;

    s920:
    tx=(rand()%33)+2;
    ty=(rand()%13)+2;
    if (*(ma+levOffset+(ty*35)+tx-36)==1) goto s920;

    targX=(tx-x)*2;
    targY=(ty-y)*2;

    asm
    {
    "call virtualFlip",
    "ld de,520","ld hl,48","call __gra_set_origin",
    "ld a,3","call __gra_set_pen",
    "ld de,(_targX)","ld hl,(_targY)","call __gra_plot_absolute",
    "call virtualFlip",
    "ld de,(_targX)","ld hl,(_targY)","call __gra_plot_absolute",
    "ld de,0","ld hl,0","call __gra_set_origin",
    "ld a,2","call __gra_set_pen"
    }

    gosub s2890;

    s980:
    flash++;
    if (flash==4) flash=0;

    asm
    {
    "call virtualFlip",
    "ld a,(_flash)","call __gra_set_pen",
    "ld de,(_mx)","ld hl,(_my)","call __gra_plot_absolute",
    "ld a,2","call __gra_set_pen",
    "call virtualFlip"
    }

    a=inkey();
    ky=0;

    if (a==224) ky=9;
    else if (a==242) ky=8;
    else if (a==243) ky=1;
    else goto s980;

    if (ky==9)
    {
      if (*(view+17)==1) goto s980;
    }
    else if (ky==8)
    {
      dir--;
      if (dir==0) dir=4;
      gosub s2890;
      goto s980;
    }
    else if (ky==1)
    {
      dir++;
      if (dir==5) dir=1;
      gosub s2890;
      goto s980;
    }

    asm
    {
    "call virtualFlip",
    "xor a","call __gra_set_pen",
    "ld de,(_mx)","ld hl,(_my)","call __gra_plot_absolute",
    "ld a,2","call __gra_set_pen",
    "call virtualFlip"
    }

    sound(129,50,0,15,2,2,0);
    moves++;

    if (dir==1)
    {
      y++;
      my+=2;
    }
    else if (dir==2)
    {
      x++;
      mx+=2;
    }
    else if (dir==3)
    {
      y--;
      my-=2;
    }
    else if (dir==4)
    {
      x--;
      mx-=2;
    }

    gosub s2890;
    if ((tx!=x) || (ty!=y)) goto s980;

    if (lev<4)
    {
      sound(129,50,200,15,0,1,0);

      for (sn=31;sn>=1;sn--)
      {
        asm
        {
        "sound_1:",
        "ld a,1","ld (soundQueue),a",
        "xor a","ld (soundQueue+1),a","ld (soundQueue+2),a","ld (soundQueue+3),a",
        "ld a,2","ld (soundQueue+7),a",
        "ld a,(_sn)","ld (soundQueue+5),a",
        "ld d,0","ld e,a","ld hl,_levSoundVol","add hl,de","ld a,(hl)","ld (soundQueue+6),a",
        "ld hl,soundQueue","call __sound_queue","jp nc,sound_1"
        }
      }

      goto s870;
    }
    else
    {
      sound(129,*(endSoundNote),*(endSoundLen),15,1,0,0);

      for (sn=1;sn<=11;sn++)
      {
        asm
        {
        "sound_2:",
        "ld a,1","ld (soundQueue),a","ld (soundQueue+1),a",
        "xor a","ld (soundQueue+2),a","ld (soundQueue+5),a",
        "ld a,15","ld (soundQueue+6),a",
        "ld a,(_sn)","ld d,0","ld e,a","ld hl,_endSoundNote","add hl,de","ld a,(hl)","ld (soundQueue+3),a",
        "ld a,(_sn)","ld d,0","ld e,a","ld hl,_endSoundLen","add hl,de","ld a,(hl)","ld (soundQueue+7),a",
        "ld hl,soundQueue","call __sound_queue","jp nc,sound_2"
        }
      }

      for (a=1;a<=40000;a++);

      asm
      {
      "call virtualFlip",
      "call __scr_clear",
      "call virtualFlip",
      "call __scr_clear"
      }

      // Hi-scores.
      if (**(hiScore+28)<moves)
      {
        wfc=1;
        goto s1230;
      }

      **(hiScore+28)=moves;
      strcpy(hiTable+294,"");
      place=14;

      for (a=14;a>=1;a--)
      {
        hsc1=**(hiScore+((a-1)*2));
        hsc2=**(hiScore+(a*2));

        if (hsc1>hsc2)
        {
          **(hiScore+(a*2))=hsc1;
          **(hiScore+((a-1)*2))=hsc2;

          strncpy(text,hiTable+(a*21),20);
          strncpy(hiTable+(a*21),hiTable+((a-1)*21),20);
          strncpy(hiTable+((a-1)*21),text,20);

          place=a-1;
        }
      }

      wfc=0;
      gosub s1230;

      asm
      {
      "ld h,16","ld a,(_place)","add a,8","ld l,a","call __txt_set_cursor",
      "ld a,2","call __txt_set_paper",
      "xor a","call __txt_set_pen"
      }

      clearinput();
      input(text);
      strncpy(hiTable+(place*21),text,20);
      wfc=1;

      s1230:
      asm
      {
      "ld a,2","call __txt_set_paper",
      "ld a,1","call __scr_set_mode",
      "call __txt_clear_window",
      "ld a,3","call __txt_set_pen",
      "ld hl,#1002","call __txt_set_cursor"
      }

      prints("3-D Maze");

      asm
      {
      "ld hl,#1003","call __txt_set_cursor",
      "call print2",
      "xor a","call __txt_set_pen",
      "ld hl,#1005","call __txt_set_cursor"
      }

      prints("HISCORES");

      asm
      {
      "ld hl,#1006","call __txt_set_cursor",
      "call print2",
      "ld a,3","call __txt_set_pen"
      }

      for (a=1;a<=15;a++)
      {
        asm{"ld h,5","ld a,(_a)","add a,7","ld l,a","call __txt_set_cursor"}
        if (a<10) prints(" ");
        prints(strltrm(btoa(text,a),48));
        prints(": ");
        prints(strltrm(wtoa(text,**(hiScore+((a-1)*2))),48));
        asm{"ld h,16","ld a,(_a)","add a,7","ld l,a","call __txt_set_cursor"}
        prints(hiTable+((a-1)*21));
      }

      asm
      {
      "ld hl,#0e18","call __txt_set_cursor",
      "xor a","call __txt_set_paper",
      "ld a,1","call __txt_set_pen"
      }

      if (wfc==0)
      {
        prints(" ENTER  NAME ");
        return;
      }
      else
      {
        prints(" PRESS A KEY ");
        clearinput();
        while (!inkey());
        goto s230;
      }
    }

    s2290:
    for (a=0;a<=10;a++)
    {
      tmp1=view+16+a;
      tmp20=y+a;
      tmp2=ma+levOffset+(tmp20*35)+x;

      *(view+a)=*(tmp2-37);
      if ((tx!=x) || (ty!=tmp20)) goto s2370;

      if (lev==4) *(tmp1)=2;
      else *(tmp1)=3;

      goto s2380;

      s2370:
      *(tmp1)=*(tmp2-36);

      s2380:
      if (otx==x) {if (oty==tmp20) {if (tmp21!=1) *(tmp1)=4;}}
      *(view+32+a)=*(tmp2-35);

      if (*(tmp1)==1) goto s2420;
    }

    s2420:
    return;

    s2440:

    for (a=0;a<=10;a++)
    {
      tmp1=view+16+a;
      tmp20=x+a;
      tmp2=ma+levOffset+(y*35)+tmp20;

      *(view+a)=*(tmp2-1);
      if ((tx!=tmp20) || (ty!=y)) goto s2520;

      if (lev==4) *(tmp1)=2;
      else *(tmp1)=3;

      goto s2530;

      s2520:
      *(tmp1)=*(tmp2-36);

      s2530:
      if (otx==tmp20) {if (oty==y) {if (tmp21!=1) *(tmp1)=4;}}
      *(view+32+a)=*(tmp2-71);

      if (*(tmp1)==1) goto s2570;
    }

    s2570:
    return;

    s2590:
    for (a=0;a<=10;a++)
    {
      tmp1=view+16+a;
      tmp20=y-a;
      tmp2=ma+levOffset+(tmp20*35)+x;

      *(view+a)=*(tmp2-35);
      if ((tx!=x) || (ty!=tmp20)) goto s2670;

      if (lev==4) *(tmp1)=2;
      else *(tmp1)=3;

      goto s2680;

      s2670:
      *(tmp1)=*(tmp2-36);

      s2680:
      if (otx==x) {if (oty==tmp20) {if (tmp21!=1) *(tmp1)=4;}}
      *(view+32+a)=*(tmp2-37);

      if (*(tmp1)==1) goto s2720;
    }

    s2720:
    return;

    s2740:
    for (a=0;a<=10;a++)
    {
      tmp1=view+16+a;
      tmp20=x-a;
      tmp2=ma+levOffset+(y*35)+tmp20;

      *(view+a)=*(tmp2-71);
      if ((tx!=tmp20) || (ty!=y)) goto s2820;

      if (lev==4) *(tmp1)=2;
      else *(tmp1)=3;

      goto s2830;

      s2820:
      *(tmp1)=*(tmp2-36);

      s2830:
      if (otx==tmp20) {if (oty==y) {if (tmp21!=1) *(tmp1)=4;}}
      *(view+32+a)=*(tmp2-1);

      if (*(tmp1)==1) goto s2870;
    }

    s2870:
    return;

    s2890:
    tmp21=*(ma+levOffset+(oty*35)+otx-36);

    if (dir==1) gosub s2290;
    else if (dir==2) gosub s2440;
    else if (dir==3) gosub s2590;
    else if (dir==4) gosub s2740;

    // Fast clear screen.
    asm
    {
    "di","ld (stackPointer),sp","ld de,0",
    "exx","ld hl,#c032",

    "ld a,iyl","cp 1","jp c,normalScreen",
    "ld de,#8000","sbc hl,de",

    "normalScreen:",
    "ld sp,hl","ld de,#50","exx",
    "ld hl,0","add hl,sp","ld c,25",

    "cls_loop1:",
    "ld b,8",

    "cls_loop2:",
    "push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de","push de",
    "ld sp,#800","add hl,sp","ld sp,hl","djnz cls_loop2",
    "exx","add hl,de","ld sp,hl","exx",
    "ld hl,0","add hl,sp","dec c","jp nz,cls_loop1",
    "ld sp,(stackPointer)","ei"
    }

    en=0;

    for (d=0;d<=10;d++)
    {
      tmp5=*(sLeft+d);
      tmp6=*(sLeft+d+1);
      tmp7=*(sRight+d);
      tmp8=*(sRight+d+1);
      tmp9=(((tmp5/8)+1)*8)-tmp5;
      tmp10=(((tmp8/8)+1)*8)-tmp8;
      tmp11=(((tmp6/8)+1)*8)-tmp6;
      tmp12=tmp7-tmp5+1;
      tmp13=tmp6-tmp5+1;
      tmp14=tmp7-tmp8+1;
      tmp15=tmp8-tmp6+1;
      tmp16=*(view+d+16);
      tmp17=*(view+d+32);
      tmp18=*(view+d+17);
      tmp19=*(view+d);

      if (tmp16!=1) goto s2980;

      asm
      {
      "ld a,(_tmp5)","ld ixh,a","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp12-1)","call drawHoriz",
      "ld a,(_tmp5)","ld ixh,a","ld a,(_tmp7)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp12-1)","call drawHoriz"
      }

      if (*(view+d-1)==1)
      {
        asm{"ld a,(_tmp5)","ld ixh,a","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp12-1)","call drawVert"}
      }

      if (*(view+31+d)==1)
      {
        asm{"ld a,(_tmp7)","ld ixh,a","ld a,(_tmp5)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp12-1)","call drawVert"}
      }

      en=1;

      s2980:
      if (en==1) goto s3080;

      if (tmp19==1)
      {
        asm
        {
        "ld a,(_tmp5)","ld ixh,a","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawDiag_down",
        "ld a,(_tmp5)","ld ixh,a","ld a,(_tmp7)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawDiag_up"
        }
      }
      else
      {
        asm
        {
        "ld a,(_tmp5)","ld ixh,a","ld a,(_tmp6)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawHoriz",
        "ld a,(_tmp5)","ld ixh,a","ld a,(_tmp8)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawHoriz"
        }
      }

      if (tmp17==1)
      {
        asm
        {
        "ld a,(_tmp8)","ld ixh,a","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp14-1)","call drawDiag_down",
        "ld a,(_tmp8)","ld ixh,a","ld a,(_tmp6)","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp14-1)","call drawDiag_up"
        }
      }
      else
      {
        asm
        {
        "ld a,(_tmp8)","ld ixh,a","ld a,(_tmp6)","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp14-1)","call drawHoriz",
        "ld a,(_tmp8)","ld ixh,a","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp14-1)","call drawHoriz"
        }
      }

      if (tmp18!=1)
      {
        if (tmp19 != *(view+d+1))
        {
          asm{"ld a,(_tmp6)","ld ixh,a","ld ixl,a","ld de,(_tmp11)","ld bc,(_tmp15-1)","call drawVert"}
        }
      }

      if (tmp18!=1)
      {
        if (tmp17 != *(view+d+33))
        {
          asm{"ld a,(_tmp8)","ld ixh,a","ld a,(_tmp6)","ld ixl,a","ld de,(_tmp11)","ld bc,(_tmp15-1)","call drawVert"}
        }
      }

      // Draw target X.
      if (tmp16==2)
      {
        asm
        {
        "ld a,1","call __gra_set_pen",

        "ld a,(_tmp5)","ld h,0","ld l,a","add hl,hl","ld d,h","ld e,l",
        "call __gra_move_absolute",

        "ld a,(_tmp8)","ld h,0","ld l,a","add hl,hl","ld d,h","ld e,l",
        "ld a,(_tmp6)","ld h,0","ld l,a","add hl,hl",
        "call __gra_line_absolute",

        "ld a,(_tmp7)","ld h,0","ld l,a","add hl,hl","ld d,h","ld e,l",
        "ld a,(_tmp5)","ld h,0","ld l,a","add hl,hl",
        "call __gra_move_absolute",

        "ld a,(_tmp6)","ld h,0","ld l,a","add hl,hl","ld d,h","ld e,l",
        "call __gra_line_absolute",

        "ld a,2","call __gra_set_pen"
        }
      }

      // Draw floor hole.
      else if (tmp16==3)
      {
        asm
        {
        "ld a,(_tmp6)","ld ixh,a","ld a,(_tmp8)","ld ixl,a","ld de,(_tmp11)","ld bc,(_tmp15-1)","call drawHoriz",
        "ld a,(_tmp5)","ld ixh,a","ld a,(_tmp7)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp12-1)","call drawHoriz",

        "ld a,(_tmp6)","ld ixh,a","ld a,(_tmp8)","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp13-1)","call drawVert",
        "ld a,(_tmp8)","ld ixh,a","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp13-1)","call drawVert",

        "ld a,(_tmp5)","ld ixh,a","ld a,(_tmp7)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawDiag_up",
        "ld a,(_tmp8)","ld ixh,a","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp13-1)","call drawDiag_down"
        }
      }

      // Draw ceiling hole.
      else if (tmp16==4)
      {
        asm
        {
        "ld a,(_tmp5)","ld ixh,a","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp12-1)","call drawHoriz",
        "ld a,(_tmp6)","ld ixh,a","ld ixl,a","ld de,(_tmp11)","ld bc,(_tmp15-1)","call drawHoriz",

        "ld a,(_tmp6)","ld ixh,a","ld a,(_tmp5)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawVert",
        "ld a,(_tmp8)","ld ixh,a","ld a,(_tmp5)","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawVert",

        "ld a,(_tmp5)","ld ixh,a","ld ixl,a","ld de,(_tmp9)","ld bc,(_tmp13-1)","call drawDiag_down",
        "ld a,(_tmp8)","ld ixh,a","ld a,(_tmp6)","ld ixl,a","ld de,(_tmp10)","ld bc,(_tmp13-1)","call drawDiag_up"
        }
      }

      en=tmp16;
    }

    s3080:
    asm
    {
    "ld a,2","call __txt_set_pen",
    "ld a,3","call __txt_set_paper",
    "ld hl,#0b08","call __txt_set_cursor"
    }

    if (moves==0) prints("0");
    else prints(strltrm(wtoa(text,moves),48));

    // Horizontal distance to target.
    tmp3=0;
    if (tx>x) tmp3=tx-x;
    else if (x>tx) tmp3=x-tx;

    // Vertical distance to target.
    tmp4=0;
    if (ty>y) tmp4=ty-y;
    else if (y>ty) tmp4=y-ty;

    // Print distance to target.
    dtt=tmp3+tmp4;
    asm{"ld hl,#0b0b","call __txt_set_cursor"}

    if (dtt==0) prints("0");
    else prints(strltrm(btoa(text,dtt),48));

    asm
    {
    "ld a,32","call __txt_output",

    "ld hl,#080f","call __txt_set_cursor",
    "ld a,32","call __txt_output",

    "ld hl,#0910","call __txt_set_cursor",
    "ld a,32","call __txt_output",

    "ld hl,#0811","call __txt_set_cursor",
    "ld a,32","call __txt_output",

    "ld hl,#0710","call __txt_set_cursor",
    "ld a,32","call __txt_output"
    }

    if (dir==1)
    {
      symbol(255,symbol_arrowUp);
      asm{"ld hl,#080f","call __txt_set_cursor"}
    }
    else if (dir==2)
    {
      symbol(255,symbol_arrowRight);
      asm{"ld hl,#0910","call __txt_set_cursor"}
    }
    else if (dir==3)
    {
      symbol(255,symbol_arrowDown);
      asm{"ld hl,#0811","call __txt_set_cursor"}
    }
    else if (dir==4)
    {
      symbol(255,symbol_arrowLeft);
      asm{"ld hl,#0710","call __txt_set_cursor"}
    }

    asm
    {
    "ld a,255","call __txt_output",

    "call virtualFlip",
    "xor a","call __gra_set_pen",
    "ld de,(_mx)","ld hl,(_my)","call __gra_plot_absolute",
    "call virtualFlip",

    "ld a,iyl","cp 1","jp c,screen4000",

    "ld iyl,0","ld a,#40","call __scr_set_base",
    "ld a,#c0","ld hl,0","call __scr_set_position",
    "ld iyh,#0","jp screenFlipped",

    "screen4000:",
    "ld iyl,1","ld a,#c0","call __scr_set_base",
    "ld a,#40","ld hl,0","call __scr_set_position",
    "ld iyh,#80",

    "screenFlipped:"
    }

    return;



    asm
    {
    "stackPointer: equ #0",
    "cmask: equ #B6A3",
    "soundQueue: defs 9",
    "bTemp: defb 0",



    "print2:",
    "ld a,45","ld b,8",

    "print2_a:",
    "call __txt_output",
    "djnz print2_a",
    "ret",



    "print3:",
    "ld a,143","ld b,9",

    "print3_a:",
    "call __txt_output",
    "djnz print3_a",
    "ret",



    "virtualFlip:",
    "ld hl,0","ld a,iyl","cp 1","jp c,virtualFlip_1",
    "ld iyl,0","ld a,#c0","jp virtualFlip_done",

    "virtualFlip_1:",
    "ld iyl,1","ld a,#40",

    "virtualFlip_done:",
    "call __scr_set_position",
    "ret",



    "pixAddr:",
    "push de",
    "ld a,ixl","ld l,a","and %00000111","ld h,a","xor l","ld l,a","ld e,a","ld d,#60","add hl,hl","add hl,hl","add hl,de","add hl,hl",
    "ld d,0","ld e,ixh","rr e","srl e","add hl,de","ld d,iyh","ld e,0","sbc hl,de",
    "pop de",

    "ld a,4","cp e","jp nc,pixAddr_ok",
    "ld a,e","sub 4","ld d,a","jp pixAddr_cont",

    "pixAddr_ok:",
    "ld d,e",

    "pixAddr_cont:",
    "ld c,%10001000","ld a,ixh","and %00000011","jp z,pixAddr_end",

    "pixAddr_shift:",
    "srl c","dec a","jp nz,pixAddr_shift",

    "pixAddr_end:",
    "ret",



    "drawHoriz:",
    "di","call pixAddr",

    "horiz_loop:",
    "ld a,(cmask)","xor (hl)","and c","xor (hl)","ld (hl),a",
    "dec d","jp z,horiz_4",
    "srl c","djnz horiz_loop","jp horiz_end",

    "horiz_4:",
    "ld d,4","inc hl","ld c,%10001000","djnz horiz_loop",

    "horiz_end:",
    "ei",
    "ret",



    "drawVert:",
    "di","ld (stackPointer),sp","ld sp,#800","call pixAddr",

    "vert_loop:",
    "ld a,(cmask)","xor (hl)","and c","xor (hl)","ld (hl),a",
    "dec e","jp z,vert_8",
    "add hl,sp","djnz vert_loop","jp vert_end",

    "vert_8:",
    "ld e,8","ld sp,#37b0","sbc hl,sp","ld sp,#800","djnz vert_loop",

    "vert_end:",
    "ld sp,(stackPointer)","ei",
    "ret",



    "drawDiag_down:",
    "di","ld (stackPointer),sp","ld sp,#800","call pixAddr",

    "diagDown_loop:",
    "ld a,(cmask)","xor (hl)","and c","xor (hl)","ld (hl),a",
    "dec d","jp z,diagDown_4",
    "dec e","add hl,sp","srl c","djnz diagDown_loop","jp diagDown_end",

    "diagDown_4:",
    "ld d,4","dec e","jp z,diagDown_8",
    "add hl,sp","inc hl","ld c,%10001000","djnz diagDown_loop","jp diagDown_end",

    "diagDown_8:",
    "ld e,8","ld sp,#37af","sbc hl,sp","ld sp,#800","ld c,%10001000","djnz diagDown_loop",

    "diagDown_end:",
    "ld sp,(stackPointer)","ei",
    "ret",



    "drawDiag_up:",
    "di","ld (stackPointer),sp","ld sp,#800","call pixAddr",

    "diagUp_loop:",
    "ld a,(cmask)","xor (hl)","and c","xor (hl)","ld (hl),a",
    "dec d","jp z,diagUp_4",
    "dec e","sbc hl,sp","srl c","djnz diagUp_loop","jp diagUp_end",

    "diagUp_4:",
    "ld d,4","dec e","jp z,diagUp_8",
    "sbc hl,sp","inc hl","ld c,%10001000","djnz diagUp_loop","jp diagUp_end",

    "diagUp_8:",
    "ld e,8","ld sp,#37b1","add hl,sp","ld sp,#800","ld c,%10001000","djnz diagUp_loop",

    "diagUp_end:",
    "ld sp,(stackPointer)","ei",
    "ret"
    }
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Great work!

    Post  Dinoneno Sat Dec 12, 2009 8:17 am

    Great! I'll post a link to this post in Amstrad.es and others webs for everybody can admire your work. I hope you do not mind.

    It is true that the code is somewhat convoluted. Perhaps if you had created and used some functions instead of assembly code would add much more readable. You could also have used the cpc6128.ccz80 library functions instead of assembly, for example:

    asm
    (
    "ld hl, # 1e19", "call __txt_set_cursor"
    "ld a, 1", "call __txt_set_paper"
    "ld a, 2", "call __txt_set_pen"
    )

    could have done:

    locate (30, 25);
    paper (1);
    pen (2);

    These are just some tips to improve readability, not to make the program work better or faster.
    avatar
    poppichicken


    Posts : 37
    Join date : 2009-10-09

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  poppichicken Mon Dec 14, 2009 10:39 am

    Hi there.

    That'll be fine! I'm looking forward to seeing what people think of it.
    I'm also hoping that this can give ccz80 a bit more exposure, because I think it is an outstanding tool.

    I actually had lots of things like:
    locate (30, 25);
    paper (1);
    pen (2);
    in the program when there wasn't much machine code in there, but I changed as much as I could to machine code in an effort to get maximum speed and minimum memory usage, and also because this is my first machine code game, and I wanted as much of it in assembler as possible.

    This is because I was having problems that seemed to be due to running out of memory, or something.
    It's strange though - I'm using a double-buffered display, so 32K is being used for the screen.
    The ROM takes up 8K (I think), and the code takes around 10K.
    That should leave 14K.

    But if I go too much over 10K with my .bin file, I start getting visual glitches, or more commonly crashes.
    I'm not sure why that is - am I doing something wrong with the ccz80 compiler?

    I'm now thinking of how I can get a flicker-free display without double buffering, in order to get all that memory back, so I can put other things into the game.
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Tue Dec 15, 2009 5:33 am

    If you try by example pen(1), this is a inline function, and the code is inserted as you use asm {...}, and is more explicit. You can see that if you write a small program and you compile with the /asm option, so you have the assembler code for view it.

    About the problem with memory, if you compile in address #8000, you have memory to adress #A6FB, as is explained in the firmware guide (in #A6FC is the first "system variable", and I prefer don't write in this addresses because can make undesired and unknow effects). So, you have #A6FB - #8000 = 9981 bytes = less 10Kbytes. The other free memory block is located from address #170 to #3FFF = 16Kbytes (in #4000 starts your double buffer, it isn't?), but this zone is not good if you use float numbers and others characteristics from CPC, I don't know the reason, maybe the ROM is overlap in address #0000 to #3FFF.

    If you can define the double buffer in a minor address, by example #1000 to #4FFF, you can compile the program in address #5000. But I think that is no possible Sad. And if you dont use #4000 to #7FFF for double buffer it's excelent.

    It this idea help you: the big array ma you can insert the data in an external file and use datafile "data.bin" = #170 and define a constant ma = #170, for put this data in address #170 and this data will not put in zone #8000 to #A6FB. This can save in this zone more bytes.
    avatar
    poppichicken


    Posts : 37
    Join date : 2009-10-09

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  poppichicken Tue Dec 15, 2009 10:23 am

    Ah, I see.
    Thanks for the information.

    I particularly like the idea of putting the data inside ma() into another bin file.
    I'll give it a try.

    EDIT: Looks like it's working! Excellent - I'll see what I can do with the extra memory.

    EDIT 2: Hmmm, something strange is going on. When I get to the 4th level of the maze (and therefore the last quarter of the data in array ma), data isn't being read correctly.
    The screen display does not work correctly, as if it has "fallen out" of the array.

    I've now tried putting this at the top of the main ccz80 file, under the include command:

    datafile "3d-maze_ma.bin"=#170;
    word ma=#170;

    It compiles, but the new bin file is 40k!
    And when I try to put this onto a dsk and run it, I get a memory full command (as expected).

    I'll see if I can figure out what is causing the stange problems with level 4.
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Tue Dec 15, 2009 11:41 pm

    Yes, it's 40K because the program starts in #170 and finish near #A000, but the memory between end of array ma and start of code is 0. You must load the new code in address #170.
    avatar
    funkheld


    Posts : 51
    Join date : 2009-12-16
    Age : 74
    Location : germany, lüneburg

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  funkheld Thu Dec 17, 2009 9:02 am

    You must load the new code in address #170.

    why with real cpc6128 ? Not Emulator !

    gruss
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Thu Dec 17, 2009 9:46 pm

    funkheld wrote:You must load the new code in address #170.

    why with real cpc6128 ? Not Emulator !

    gruss

    I think that is the same in emulator and in real cpc6128.
    avatar
    funkheld


    Posts : 51
    Join date : 2009-12-16
    Age : 74
    Location : germany, lüneburg

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  funkheld Thu Dec 17, 2009 11:43 pm

    ohhh...

    In the real cpc not funktion with #170 und im the emu not funktion with #170.

    The cpc for openin/openout 4000byte reserviert.

    gruss
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Thu Dec 17, 2009 11:49 pm

    If #170 is an address too low, it must change the game code with, by example:

    word ma=#2000;
    datafile "3d-maze_ma.bin"=ma;

    With the value #1000 I think it's good for load the file 3d-maze_ma.bin without overwrite the address #4000, that is reserved for double buffer.
    avatar
    funkheld


    Posts : 51
    Join date : 2009-12-16
    Age : 74
    Location : germany, lüneburg

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  funkheld Fri Dec 18, 2009 12:39 am

    Error : file not found...

    Code:

    include "cpc6128.ccz80";

    word ma=#2000;
    datafile "3d-maze_ma.bin"=ma;

    byte dir;
    byte en;
    byte d;
    ......
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Fri Dec 18, 2009 12:47 am

    Sorry, I don't say that the file 3d-maze_ma.bin may content the values of array ma, and remove this array from program. Poppichicken is working in that, but I don't know if he has finish and publish this work.
    avatar
    poppichicken


    Posts : 37
    Join date : 2009-10-09

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  poppichicken Fri Dec 18, 2009 11:30 am

    Hi Dinoneno.

    Thanks very very much for all of your help so far.
    I have a quick question:

    I'm using this tiny program for a test.
    Code:
    include "cpc6128.ccz80";
    word ma=#0170;
    datafile "3d-maze_ma.bin"=ma;
    return;
    Compiling it (at #8000) gives me the following error:
    ERROR: identifier already defined in file C:\ccz80\3d-maze.ccz80 line 4 position 27
    datafile "3d-maze_ma.bin"=ma;


    So I tried the following program instead.
    Code:
    include "cpc6128.ccz80";
    word ma=#0170;
    datafile "3d-maze_ma.bin"=#0170;
    return;
    That compiles, but when I run it, it simply resets the CPC.

    If I remove the datafile statement, it runs.
    It doesn't do anything of course, but it compiles, and after I run it, the CPC returns to the Ready prompt as expected.

    I'm having trouble figuring out how to use datafile correctly.
    avatar
    funkheld


    Posts : 51
    Join date : 2009-12-16
    Age : 74
    Location : germany, lüneburg

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  funkheld Fri Dec 18, 2009 7:49 pm

    hello!

    3d-maze_ma.bin > the dsk

    start in cpc6128:

    Code:

    include "cpc6128.ccz80";
    word ma=#0170;
    datafile "3d-maze_ma.bin"=#0170;
    return;

    load"3d-maze_ma.bin",&170 > not funktion
    load"3d-maze_ma.bin" > not funktion
    run"3d-maze_ma.bin",&170 > not funktion
    run"3d-maze_ma.bin > not funktion
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Fri Dec 18, 2009 11:21 pm

    poppichicken wrote:Hi Dinoneno.

    Thanks very very much for all of your help so far.
    I have a quick question:

    I'm using this tiny program for a test.
    Code:
    include "cpc6128.ccz80";
    word ma=#0170;
    datafile "3d-maze_ma.bin"=ma;
    return;
    Compiling it (at #8000) gives me the following error:
    ERROR: identifier already defined in file C:\ccz80\3d-maze.ccz80 line 4 position 27
    datafile "3d-maze_ma.bin"=ma;


    So I tried the following program instead.
    Code:
    include "cpc6128.ccz80";
    word ma=#0170;
    datafile "3d-maze_ma.bin"=#0170;
    return;
    That compiles, but when I run it, it simply resets the CPC.

    If I remove the datafile statement, it runs.
    It doesn't do anything of course, but it compiles, and after I run it, the CPC returns to the Ready prompt as expected.

    I'm having trouble figuring out how to use datafile correctly.

    Hello. About that question, you can not define a variable ma with "word ma=#170" and do "datafile "3d-maze_ma.bin"=ma", because you has defined a varible ma and so, with the datafile instruction, you define a laber named ma for pointer the data of file 3d-maze_ma.bin (see manual). You must define ma as a constant: "const ma=#170", and in the data file instruction is done a substitution of ma for the value #170.
    avatar
    Dinoneno


    Posts : 115
    Join date : 2008-01-15
    Age : 53
    Location : Toledo

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Dinoneno Fri Dec 18, 2009 11:44 pm

    funkheld wrote:hello!

    3d-maze_ma.bin > the dsk

    start in cpc6128:

    Code:

    include "cpc6128.ccz80";
    word ma=#0170;
    datafile "3d-maze_ma.bin"=#0170;
    return;

    load"3d-maze_ma.bin",&170 > not funktion
    load"3d-maze_ma.bin" > not funktion
    run"3d-maze_ma.bin",&170 > not funktion
    run"3d-maze_ma.bin > not funktion

    And about that, that are two concepts diferents: with datafile you include the data of 3d-maze_ma.bin when compiling, and the data is in the executable .bin created; the other concept is use load or run in the emulator or CPC for load a file in the memory.

    The utility of datafile is that (this program can be named program.ccz80):

    Code:

    include "cpc6128.ccz80"; // include all definitions of functions for use with CPC 6128
    const address_array = #1000
    datafile "data.dat"=address_array; // I supose the file data.dat is 10 bytes lenght
    word pointer = #address_array;
    repeat (10) { printb(*pointer); ++pointer; } // Display all values of data.dat, for do something
    return;

    This program can be compiled, by example, with "ccz80 program.ccz80 /org=#4000" for create the executable from address #4000.

    If all is ok, you can copy the created .bin in a dsk file, load the dsk in the emulator, and write:

    memory &3fff ' For reserve memory from #4000 to up
    load "program.bin",&1000 // The program must be loaded in #1000, because you have the array in #1000 (it's the less address use in program)
    // If you don't use datafile, the less address is #4000 because you have only code from #4000 to #4100 near
    // As you include data.da in address #1000, the .bin has the next structure:
    // #1000 to #1009: data of data.data
    // #100A to #3FFF: blank
    // #4000 to #4100 near: code of program
    // For optimize the space, you can load data.bin in #3FF6, so the structure of program.bin is:
    // #3FF6 to #3FFF: data of data.data
    // #4000 to #4100 near: code of program
    call &4000 ' The entry point of code of program is #4000

    I hope that my English can be useful for explain that, but my German is null Sad .


    Last edited by Dinoneno on Sat Dec 19, 2009 5:23 am; edited 1 time in total (Reason for editing : Error in code: for comment ' must be //)
    avatar
    funkheld


    Posts : 51
    Join date : 2009-12-16
    Age : 74
    Location : germany, lüneburg

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  funkheld Sat Dec 19, 2009 5:14 am

    jup, thanks. it ok !!!

    gruss
    peter
    avatar
    poppichicken


    Posts : 37
    Join date : 2009-10-09

    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  poppichicken Sun Dec 20, 2009 11:02 pm

    Ah, I see.
    Thanks once again for your very generous help.

    Sponsored content


    3D-Maze game for Amstrad CPC Empty Re: 3D-Maze game for Amstrad CPC

    Post  Sponsored content


      Current date/time is Fri Mar 29, 2024 4:40 pm