123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- unit scrolling;
- interface
- uses
- ctypes, nds9, RotBackgrounds, TextBackgrounds, Multilayer;
- procedure scroll(id, width, height: cint);
- procedure scrollText();
- procedure scrollRotation();
- procedure scrollVertical();
- procedure scrollHorizontalText();
- procedure scrollHorizontalExRotation();
- procedure scroll4wayText();
- procedure scroll4wayExRotation();
- implementation
- //reusable scroll function to allow the user to explore
- //the maps somewhat
- procedure scroll(id, width, height: cint);
- var
- keys, sx, sy: integer;
- begin
- keys := 0;
- sx := 0;
- sy := 0;
- while (keys and KEY_B) = 0 do
- begin
- scanKeys();
- keys := keysHeld();
- if (keys and KEY_UP) <> 0 then dec(sy);
- if (keys and KEY_DOWN) <> 0 then inc(sy);
- if (keys and KEY_LEFT) <> 0 then dec(sx);
- if (keys and KEY_RIGHT) <> 0 then inc(sx);
- if (sx < 0) then sx := 0;
- if (sx >= width - 256) then sx := width - 1 - 256;
- if (sy < 0) then sy := 0;
- if (sy >= height - 192) then sy := height - 1 - 192;
- swiWaitForVBlank();
- bgSetScroll(id, sx, sy);
- bgUpdate();
- consoleClear();
- iprintf('Scroll x: %d Scroll y: %d'#10, sx, sy);
- iprintf('Press ''B'' to exit');
- end;
- end;
- procedure scrollText();
- var
- keys, sx, sy, width, height: integer;
- bg: cint;
- begin
- keys := 0;
- sx := 0;
- sy := 0;
- width := 256;
- height := 512;
- //set up a simple text background
- videoSetMode(MODE_0_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- bg := bgInit(0, BgType_Text8bpp, BgSize_T_256x512, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@Layer256x512Map, bgGetMapPtr(bg), Layer256x512MapLen);
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- while (keys and KEY_B) = 0 do
- begin
- scanKeys();
- keys := keysHeld();
- if (keys and KEY_UP) <> 0 then dec(sy);
- if (keys and KEY_DOWN) <> 0 then inc(sy);
- if (keys and KEY_LEFT) <> 0 then dec(sx);
- if (keys and KEY_RIGHT) <> 0 then inc(sx);
- //clamp the scroll value to the map width and height
- if (sx < 0) then sx := 0;
- if (sx >= width - 256) then sx := width - 1 - 256;
- if (sy < 0) then sy := 0;
- if (sy >= height - 192) then sy := height - 1 - 192;
- swiWaitForVBlank();
- //normally would call bgSetScroll(id, sx, sy) here
- //but to demonstrate the hardware difference between
- //scrolling rotation and text backgrounds we will use
- //direct register access
- REG_BG0HOFS^ := sx;
- REG_BG0VOFS^ := sy;
- consoleClear();
- iprintf('Scroll x: %d Scroll y: %d'#10, sx, sy);
- iprintf('Press ''B'' to exit');
- end;
- end;
- procedure scrollRotation();
- var
- keys, sx, sy, width, height: integer;
- bg: cint;
- begin
- keys := 0;
- sx := 0;
- sy := 0;
- width := 512;
- height := 512;
- videoSetMode(MODE_5_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- bg := bgInit(3, BgType_ExRotation, BgSize_ER_512x512, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- dmaCopy(@Layer512x512Map, bgGetMapPtr(bg), Layer512x512MapLen);
- while (keys and KEY_B)=0 do
- begin
- scanKeys();
- keys := keysHeld();
- if (keys and KEY_UP) <> 0 then dec(sy);
- if (keys and KEY_DOWN) <> 0 then inc(sy);
- if (keys and KEY_LEFT) <> 0 then dec(sx);
- if (keys and KEY_RIGHT) <> 0 then inc(sx);
- //clamp the scroll value to the map width and height
- if (sx < 0) then sx := 0;
- if (sx >= width - 256) then sx := width - 1 - 256;
- if (sy < 0) then sy := 0;
- if (sy >= height - 192) then sy := height - 1 - 192;
- swiWaitForVBlank();
- //normally would call bgSetScroll(id, sx, sy) here
- //but to demonstrate the hardware difference between
- //scrolling rotation and text backgrounds we will use
- //direct register access
- REG_BG3X^ := sx shl 8;
- REG_BG3Y^ := sy shl 8;
- consoleClear();
- iprintf('Scroll x: %d Scroll y: %d'#10, sx, sy);
- iprintf('Press ''B'' to exit');
- end;
- end;
- procedure scrollVertical();
- var
- scroll_y: integer = 0;
- map: pcuint16;
- bg: cint;
- keys: integer = 0;
- offset: integer = 0;
- begin
- videoSetMode(MODE_0_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- scroll_y := 0;
- bg := bgInit(0, BgType_Text8bpp, BgSize_T_256x256, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- map := pcuint16(bgGetMapPtr(bg));
- dmaCopy(@Layer256x512Map, map, 32*32*2);
- keys := 0;
- offset := 0;
- while (keys and KEY_B)= 0 do
- begin
- scanKeys();
- keys := keysHeld();
- swiWaitForVBlank();
- if (keys and KEY_UP) <> 0 then
- begin
- offset := scroll_y div 8 - 1;
- dmaCopy(@Layer256x512Map[(offset and 63) * 32], @map[(offset and 31) * 32], 32 * 2);
- dec(scroll_y);
- end;
-
- if (keys and KEY_DOWN) <> 0 then
- begin
- offset := scroll_y div 8 + 24;
- dmaCopy(@Layer256x512Map[(offset and 63) * 32], @map[(offset and 31) * 32], 32 * 2);
- inc(scroll_y);
- end;
- bgSetScroll(bg, 0, scroll_y);
- bgUpdate();
- end;
- end;
- procedure scrollHorizontalText();
- var
- scroll_x: integer = 0;
- bg: cint;
- map: pcuint16;
- iy: integer;
- keys: integer = 0;
- layerOffset: integer = 0;
- mapOffset: integer = 0;
- begin
- videoSetMode(MODE_5_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- bg := bgInit(0, BgType_Text8bpp, BgSize_T_512x256, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- map := pcuint16(bgGetMapPtr(bg));
- for iy := 0 to 23 do
- dmaCopy(@Layer512x256Map[iy * 64], @map[iy * 32], 32*2);
- while (keys and KEY_B) = 0 do
- begin
- scanKeys();
- keys := keysHeld();
- swiWaitForVBlank();
- if (keys and KEY_LEFT) <> 0 then
- begin
- mapOffset := scroll_x div 8 - 1;
- layerOffset := (mapOffset and 63);
- if(layerOffset >= 32) then layerOffset := layerOffset + (32 * 32 - 32);
- for iy := 0 to 23 do
- map[layerOffset + (iy * 32)] := Layer512x256Map[(mapOffset and 63) + (iy * 64)] ;
- dec(scroll_x);
- end;
-
- if (keys and KEY_RIGHT) <> 0 then
- begin
- mapOffset := scroll_x div 8 + 32;
- layerOffset := (mapOffset and 63);
- if(layerOffset >= 32) then layerOffset := layerOffset + (32 * 32 - 32);
- for iy := 0 to 23 do
- map[layerOffset + (iy * 32)] := Layer512x256Map[(mapOffset and 63) + (iy * 64)] ;
- inc(scroll_x);
- end;
- bgSetScroll(bg, scroll_x, 0);
- bgUpdate();
- end;
- end;
- procedure scrollHorizontalExRotation();
- var
- scroll_x: integer = 0;
- bg: cint;
- map: pcuint16;
- iy: integer;
- keys: integer = 0;
- offset: integer = 0;
- begin
- videoSetMode(MODE_5_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- bg := bgInit(3, BgType_ExRotation, BgSize_ER_512x512, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- map := pcuint16(bgGetMapPtr(bg));
- bgSetControlBits(bg, BG_WRAP_ON);
- for iy := 0 to 23 do
- dmaCopy(@Layer512x256Map[iy * 64], @map[iy * 64], 32*2);
- while (keys and KEY_B) = 0 do
- begin
- scanKeys();
- keys := keysHeld();
- swiWaitForVBlank();
- if (keys and KEY_LEFT) <> 0 then
- begin
- offset := scroll_x div 8 - 1;
- for iy := 0 to 23 do
- map[(offset and 63) + (iy * 64)] := Layer512x256Map[(offset and 63) + (iy * 64)] ;
- dec(scroll_x);
- end;
-
- if (keys and KEY_RIGHT) <> 0 then
- begin
- offset := scroll_x div 8 + 32;
- for iy := 0 to 23 do
- map[(offset and 63) + (iy * 64)] := Layer512x256Map[(offset and 63) + (iy * 64)] ;
- inc(scroll_x);
- end;
- bgSetScroll(bg, scroll_x, 0);
- bgUpdate();
- end;
- end;
- //scrolls a 1024 by 1024 map on a 512x512 layer
- procedure scroll4wayText();
- var
- scroll_x: integer = 0;
- scroll_y: integer = 0;
- bg: cint;
- bgTileMap, bgLeftHalf, bgRightHalf: pcuint16;
- ix, iy: integer;
- keys: integer = 0;
- offset_x: integer = 0;
- offset_y: integer = 0;
- movingHorizontal: boolean = false;
- movingVertical: boolean = false;
- bgTemp: pcuint16;
- const
- tileWidth : integer = 8; //width of a tile in pixels
- mapWidth : integer = 1024 div 8; //width of the big map in tiles
- mapHeight : integer = 1024 div 8; //heigh of the big map in tiles
- bgWidth : integer = 256 div 8; //width of the hardware map in tiles
- bgHeight : integer = 256 div 8; //height of the hardware map in tiles
- screenWidth : integer = 256 div 8; //screen width in tiles
- screenHeight: integer = 192 div 8; //screen height in tiles
- begin
- videoSetMode(MODE_0_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- bg := bgInit(3, BgType_Text8bpp, BgSize_T_512x256, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- bgTileMap := pcuint16(bgGetMapPtr(bg));
- bgLeftHalf := bgTileMap;
- bgRightHalf := bgTileMap + 32 * 32;
- for iy := 0 to screenHeight - 1 do
- dmaCopy(@Layer1024x1024Map[iy * mapWidth], @bgTileMap[iy * bgWidth], screenWidth * 2);
- while (keys and KEY_B) = 0 do
- begin
- movingHorizontal := false;
- movingVertical := false;
- scanKeys();
- keys := keysHeld();
- swiWaitForVBlank();
- if (keys and KEY_LEFT) <> 0 then
- begin
- offset_x := scroll_x div 8 - 1;
- dec(scroll_x);
- if(scroll_x < 0) then
- scroll_x := 0
- else
- movingHorizontal := true;
- end else
- if (keys and KEY_RIGHT) <> 0 then
- begin
- offset_x := scroll_x div 8 + screenWidth;
- inc(scroll_x);
- if (scroll_x >= (mapWidth - screenWidth) * tileWidth) then
- scroll_x := (mapWidth - screenWidth) * tileWidth - 1
- else
- movingHorizontal := true;
- end;
- if (keys and KEY_UP) <> 0 then
- begin
- offset_y := scroll_y div 8 - 1;
- dec(scroll_y);
- if(scroll_y < 0) then
- scroll_y := 0
- else
- movingVertical := true;
- end else
- if (keys and KEY_DOWN) <> 0 then
- begin
- offset_y := scroll_y div 8 + screenHeight;
- inc(scroll_y);
- if(scroll_y >= (mapHeight - screenHeight) * tileWidth) then
- scroll_y := (mapHeight - screenHeight) * tileWidth - 1
- else
- movingVertical := true;
- end;
- if (movingHorizontal) then
- begin
- if (offset_x and 63) >= bgWidth then
- bgTemp := bgRightHalf
- else
- bgTemp := bgLeftHalf;
- for iy := scroll_y div 8 - 1 to scroll_y div 8 + screenHeight do
- bgTemp[(offset_x and (bgWidth - 1)) + (iy and (bgHeight - 1)) * 32] := Layer1024x1024Map[offset_x + iy * mapWidth];
- end;
-
- if (movingVertical) then
- begin
- for ix := scroll_x div 8 - 1 to scroll_x div 8 + screenWidth do
- begin
- if ((ix and 63) >= bgWidth) then
- bgTemp := bgRightHalf
- else
- bgTemp := bgLeftHalf;
- bgTemp[(ix and (bgWidth - 1)) + (offset_y and (bgHeight - 1))* 32] := Layer1024x1024Map[ix + offset_y * mapWidth];
- end;
- end;
- bgSetScroll(bg, scroll_x, scroll_y);
- bgUpdate();
- end;
- end;
- procedure scroll4wayExRotation();
- var
- scroll_x: integer = 0;
- scroll_y: integer = 0;
- bgTileMap: pcuint16;
- iy, ix: integer;
- keys: integer = 0;
- offset_x: integer = 0;
- offset_y: integer = 0;
- movingHorizontal: boolean = false;
- movingVertical: boolean = false;
- bg: cint;
- const
- tileWidth : integer = 8;
- mapWidth : integer = 1024 div 8;
- mapHeight : integer = 1024 div 8;
- bgWidth : integer = 512 div 8;
- bgHeight : integer = 512 div 8;
- screenWidth : integer = 256 div 8;
- screenHeight: integer = 192 div 8;
- begin
- videoSetMode(MODE_5_2D);
- vramSetBankA(VRAM_A_MAIN_BG);
- bg := bgInit(3, BgType_ExRotation, BgSize_ER_512x512, 0,1);
- dmaCopy(@TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
- dmaCopy(@TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
- bgTileMap := pcuint16(bgGetMapPtr(bg));
- bgSetControlBits(bg, BG_WRAP_ON);
- for iy := 0 to screenHeight - 1 do
- dmaCopy(@Layer1024x1024Map[iy * mapWidth], @bgTileMap[iy * bgWidth], screenWidth * 2);
- while (keys and KEY_B) = 0 do
- begin
- movingHorizontal := false;
- movingVertical := false;
- scanKeys();
- keys := keysHeld();
- swiWaitForVBlank();
- if (keys and KEY_LEFT) <> 0 then
- begin
- offset_x := scroll_x div 8 - 1;
- dec(scroll_x);
- if(scroll_x < 0) then
- scroll_x := 0
- else
- movingHorizontal := true;
- end else
- if (keys and KEY_RIGHT) <> 0 then
- begin
- offset_x := scroll_x div 8 + screenWidth;
- inc(scroll_x);
- if (scroll_x >= (mapWidth - screenWidth) * tileWidth) then
- scroll_x := (mapWidth - screenWidth) * tileWidth - 1
- else
- movingHorizontal := true;
- end;
- if (keys and KEY_UP) <> 0 then
- begin
- offset_y := scroll_y div 8 - 1;
- dec(scroll_y);
- if(scroll_y < 0) then
- scroll_y := 0
- else
- movingVertical := true;
- end else
- if(keys and KEY_DOWN) <> 0 then
- begin
- offset_y := scroll_y div 8 + screenHeight;
- inc(scroll_y);
- if(scroll_y >= (mapHeight - screenHeight) * tileWidth) then
- scroll_y := (mapHeight - screenHeight) * tileWidth - 1
- else
- movingVertical := true;
- end;
- if (movingHorizontal) then
- begin
- for iy := scroll_y div 8 - 1 to scroll_y div 8 + screenHeight do
- bgTileMap[(offset_x and (bgWidth - 1)) + (iy and (bgHeight - 1)) * bgWidth] := Layer1024x1024Map[offset_x + iy * mapWidth];
- end;
- if (movingVertical) then
- begin
- for ix := scroll_x div 8 - 1 to scroll_x div 8 + screenWidth do
- bgTileMap[(ix and (bgWidth - 1)) + (offset_y and (bgHeight - 1))* bgWidth] := Layer1024x1024Map[ix + offset_y * mapWidth];
- end;
- bgSetScroll(bg, scroll_x, scroll_y);
- bgUpdate();
- end;
- end;
- end.
|