Compare commits
119 Commits
v1.0.0-bet
...
master
Author | SHA1 | Date |
---|---|---|
Lucas Scharenbroich | aae8fed1c1 | |
Lucas Scharenbroich | d12bddae48 | |
Lucas Scharenbroich | 94d907fd09 | |
Lucas Scharenbroich | 96549b0c21 | |
Lucas Scharenbroich | 8d7d4a8ec6 | |
Lucas Scharenbroich | aaf70af236 | |
Lucas Scharenbroich | 4ee67fb8be | |
Lucas Scharenbroich | 3eba3fa8e6 | |
Lucas Scharenbroich | 4feb94f5c6 | |
Lucas Scharenbroich | 3a4169cce4 | |
Lucas Scharenbroich | 788f938647 | |
Lucas Scharenbroich | 3c4cf89ecf | |
Lucas Scharenbroich | 89a56d479e | |
Lucas Scharenbroich | a5498e07eb | |
Lucas Scharenbroich | c7a143b488 | |
Lucas Scharenbroich | 869d80af1e | |
Lucas Scharenbroich | 515ec5280b | |
Lucas Scharenbroich | ed01a8da8d | |
Lucas Scharenbroich | 57f57ce533 | |
Lucas Scharenbroich | 77fbe4a5ad | |
Lucas Scharenbroich | df32442fff | |
Lucas Scharenbroich | e013ff03fd | |
Lucas Scharenbroich | b449d983ee | |
Lucas Scharenbroich | 44c51217a1 | |
dependabot[bot] | 6ba595f0b5 | |
Lucas Scharenbroich | dc5742dd11 | |
Lucas Scharenbroich | 02bc6fe493 | |
Lucas Scharenbroich | 4f81c4a84b | |
Lucas Scharenbroich | 36df558a3f | |
dependabot[bot] | 40bd890497 | |
Lucas Scharenbroich | de26e300c4 | |
Lucas Scharenbroich | e6ab9a22e1 | |
Lucas Scharenbroich | b154bcf361 | |
Lucas Scharenbroich | 7aec32ced5 | |
Lucas Scharenbroich | 065603a758 | |
Lucas Scharenbroich | d31bd30649 | |
Lucas Scharenbroich | 7dd690ac04 | |
Lucas Scharenbroich | 9021ee4506 | |
Lucas Scharenbroich | 5cfefc350c | |
Lucas Scharenbroich | e3409f92fa | |
Lucas Scharenbroich | 899c6c9770 | |
Lucas Scharenbroich | 070d038f06 | |
Lucas Scharenbroich | c04bf0d323 | |
Lucas Scharenbroich | 9fba232df0 | |
Lucas Scharenbroich | 3a78398ea7 | |
Lucas Scharenbroich | 39163ea786 | |
Lucas Scharenbroich | c533d846d7 | |
Lucas Scharenbroich | 6c5e133b17 | |
Lucas Scharenbroich | 029ab62f0c | |
Lucas Scharenbroich | a70412211c | |
Lucas Scharenbroich | 536959619f | |
Lucas Scharenbroich | 85cce2fe82 | |
Lucas Scharenbroich | 594b36a953 | |
Lucas Scharenbroich | 011f5c0419 | |
Lucas Scharenbroich | 04681447a5 | |
Lucas Scharenbroich | 4bfdeae6aa | |
Lucas Scharenbroich | 5697737a93 | |
Lucas Scharenbroich | 6832c7f405 | |
Lucas Scharenbroich | dd9ced08f1 | |
Lucas Scharenbroich | c14f3c7283 | |
Lucas Scharenbroich | e2e30dfcf4 | |
Lucas Scharenbroich | 981182592e | |
Lucas Scharenbroich | af6e022454 | |
Lucas Scharenbroich | 46a88b1d22 | |
dependabot[bot] | 8921086e19 | |
Lucas Scharenbroich | 31ca627c14 | |
Lucas Scharenbroich | 2af4dddb8e | |
Lucas Scharenbroich | f8fe9e40cb | |
Lucas Scharenbroich | 48bf7145d8 | |
Lucas Scharenbroich | 50930af362 | |
Lucas Scharenbroich | 4b50fa8318 | |
Lucas Scharenbroich | 50b15a8276 | |
Lucas Scharenbroich | 4ea9b5c775 | |
Lucas Scharenbroich | ff542c9575 | |
dependabot[bot] | f0110acd84 | |
Lucas Scharenbroich | b8a7641307 | |
Lucas Scharenbroich | eaedee546e | |
Lucas Scharenbroich | 217a1176a9 | |
Lucas Scharenbroich | 33da3d4a97 | |
Lucas Scharenbroich | 0b31e9ead2 | |
Lucas Scharenbroich | 6bb2c437e3 | |
Lucas Scharenbroich | 95cf3d18bb | |
Lucas Scharenbroich | 700a3124fd | |
Lucas Scharenbroich | 10729c59a9 | |
Lucas Scharenbroich | 1a7fe4bd1a | |
Lucas Scharenbroich | 3fa0f94aaf | |
Lucas Scharenbroich | bd1de7f83c | |
Lucas Scharenbroich | 3fce46872d | |
Lucas Scharenbroich | e378dc6e26 | |
Lucas Scharenbroich | 4815254d5f | |
Lucas Scharenbroich | 273cf2572c | |
Lucas Scharenbroich | 093bc738f0 | |
Lucas Scharenbroich | 97fa45589b | |
Lucas Scharenbroich | 5883de1f71 | |
Lucas Scharenbroich | 7a6c4e5ff4 | |
Lucas Scharenbroich | 4c21d6e217 | |
Lucas Scharenbroich | bc5229b528 | |
Lucas Scharenbroich | 0915f5e93b | |
Lucas Scharenbroich | 794bc1fc09 | |
Lucas Scharenbroich | a33779ae28 | |
Lucas Scharenbroich | 7c32c89493 | |
Lucas Scharenbroich | 456744027d | |
Lucas Scharenbroich | f5cad6b4dc | |
Lucas Scharenbroich | b3beca91fd | |
Lucas Scharenbroich | babd4d06b4 | |
Lucas Scharenbroich | dedb657546 | |
Lucas Scharenbroich | fa731f4b2d | |
Lucas Scharenbroich | 0f920acd03 | |
Lucas Scharenbroich | f5a27362a7 | |
Lucas Scharenbroich | e25b5b4d7f | |
Dan Malec | 9849c6bbb1 | |
Lucas Scharenbroich | 5a0e0e447e | |
Lucas Scharenbroich | 68b8ca5856 | |
Lucas Scharenbroich | d332783c85 | |
Lucas Scharenbroich | 2e578148d9 | |
Lucas Scharenbroich | eb8f21acdd | |
Lucas Scharenbroich | 58426043fc | |
dependabot[bot] | 353c164f6b | |
dependabot[bot] | fd9549d147 |
|
@ -4,4 +4,5 @@ emu
|
|||
*_Output.txt
|
||||
src/GTETestApp
|
||||
*.2mg
|
||||
Tool160.SHK
|
||||
Tool160.SHK
|
||||
src/Tool160
|
|
@ -0,0 +1,191 @@
|
|||
/* ********************************************************************
|
||||
|
||||
GTE is copyright Lucas Scharenbroich and licensed under the Apache-2.0
|
||||
License.
|
||||
|
||||
The following GTE function definitions are taken from the GTE Toolbox
|
||||
documentation:
|
||||
https://lscharen.github.io/iigs-game-engine/toolboxref.html
|
||||
|
||||
And from the GTE Macros:
|
||||
https://github.com/lscharen/iigs-game-engine/blob/d7be9f1be44748b0180c930b1f90b144cda661ea/macros/GTE.Macs.s
|
||||
|
||||
The contents of this file are a derivite work from GTE intended to
|
||||
ease the process of calling GTE / Tool 160 from ORCA/C and are believed
|
||||
to be permitted under the terms of the Apache-2.0 License.
|
||||
|
||||
********************************************************************* */
|
||||
|
||||
#ifndef _GTE_HEADER_INCLUDE_
|
||||
#define _GTE_HEADER_INCLUDE_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
GTE_IS_USER_TOOL is a boolean toggle for controlling what the application assumes about the location of
|
||||
the GTE tool.
|
||||
|
||||
If GTE is NOT installed in System:Tools, GTE_IS_USER_TOOL must be defined and the calling program
|
||||
is responsible for loading and initializing the toolset using InitialLoad and SetTSPtr.
|
||||
*/
|
||||
#ifdef GTE_IS_USER_TOOL
|
||||
#define tool_dispatcher 0xE10008L
|
||||
#else
|
||||
#define tool_dispatcher dispatcher
|
||||
#endif // GTE_IS_USER_TOOL
|
||||
|
||||
typedef struct TileMapInfo {
|
||||
Word width;
|
||||
Word height;
|
||||
Pointer tileMapPtr;
|
||||
} TileMapInfo;
|
||||
|
||||
typedef struct ScreenInfo {
|
||||
Word x;
|
||||
Word y;
|
||||
Word width;
|
||||
Word height;
|
||||
} ScreenInfo;
|
||||
|
||||
/* GTE Housekeeping Routines */
|
||||
extern pascal void GTEBootInit(void) inline(0x01A0, tool_dispatcher);
|
||||
extern pascal void GTEStartUp(Word dPageAddr, Word capFlags, Word userID) inline(0x02A0, tool_dispatcher);
|
||||
extern pascal void GTEShutDown(void) inline(0x03A0, tool_dispatcher);
|
||||
extern pascal Word GTEVersion(void) inline(0x04A0, tool_dispatcher);
|
||||
extern pascal void GTEReset(void) inline(0x05A0, tool_dispatcher);
|
||||
extern pascal Word GTEStatus(void) inline(0x06A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Sprite Routines */
|
||||
extern pascal void GTECreateSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x0FA0, tool_dispatcher);
|
||||
extern pascal Word GTECompileSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x2DA0, tool_dispatcher);
|
||||
extern pascal void GTEAddSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr, Word x, Word y) inline(0x10A0, tool_dispatcher);
|
||||
extern pascal void GTEMoveSprite(Word spriteSlot, Word x, Word y) inline(0x11A0, tool_dispatcher);
|
||||
extern pascal void GTEUpdateSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr) inline(0x12A0, tool_dispatcher);
|
||||
extern pascal void GTERemoveSprite(Word spriteSlot) inline(0x13A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Tile Routines */
|
||||
extern pascal void GTELoadTileSet(Word start, Word finish, Pointer tileSetPtr) inline(0x0EA0, tool_dispatcher);
|
||||
extern pascal void GTEFillTileStore(Word tileID) inline(0x25A0, tool_dispatcher);
|
||||
extern pascal void GTESetTile(Word xTile, Word yTile, Word tileID) inline(0x0BA0, tool_dispatcher);
|
||||
extern pascal void GTECopyTileToDynamic(Word tileID, Word dynID) inline(0x15A0, tool_dispatcher);
|
||||
extern pascal Word GTEGetTileAt(Word x, Word y) inline(0x1CA0, tool_dispatcher);
|
||||
extern pascal Pointer GTEGetTileDataAddr() inline(0x24A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Primary Background Routines */
|
||||
extern pascal void GTESetBG0Origin(Word x, Word y) inline(0x0CA0, tool_dispatcher);
|
||||
extern pascal void GTERender(Word flags) inline(0x0DA0, tool_dispatcher);
|
||||
extern pascal void GTERefresh() inline(0x26A0, tool_dispatcher);
|
||||
extern pascal struct TileMapInfo GTEGetBG0TileMapInfo() inline(0x19A0, tool_dispatcher);
|
||||
extern pascal void GTESetBG0TileMapInfo(Word width, Word height, Pointer tileMapPtr) inline(0x1DA0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Secondary Background Routines */
|
||||
extern pascal void GTESetBG1Origin(Word x, Word y) inline(0x1BA0, tool_dispatcher);
|
||||
extern pascal void GTECopyPicToBG1(Word width, Word height, Word stride, Pointer picPtr) inline(0x17A0, tool_dispatcher);
|
||||
extern pascal void GTESetBG1TileMapInfo(Word width, Word height, Pointer tileMapPtr) inline(0x1EA0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Global State Functions */
|
||||
extern pascal void GTESetScreenMode(Word width, Word height) inline(0x0AA0, tool_dispatcher);
|
||||
extern pascal void GTESetPalette(Word palNum, Pointer palettePtr) inline(0x16A0, tool_dispatcher);
|
||||
extern pascal void GTEBindSCBArray(Pointer scbPtr) inline(0x18A0, tool_dispatcher);
|
||||
extern pascal struct ScreenInfo GTEGetScreenInfo() inline(0x1AA0, tool_dispatcher);
|
||||
extern pascal void GTESetBG1Displacement(Word offset) inline(0x27A0, tool_dispatcher);
|
||||
extern pascal void GTESetBG1Rotation(Word rotIndex) inline(0x28A0, tool_dispatcher);
|
||||
extern pascal void GTEClearBG1Buffer(Word value) inline(0x29A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Misc. Functions */
|
||||
extern pascal Word GTEReadControl(void) inline(0x09A0, tool_dispatcher);
|
||||
extern pascal Word GTEGetSeconds(void) inline(0x14A0, tool_dispatcher);
|
||||
extern pascal Pointer GTEGetAddress(Word tableId) inline(0x2CA0, tool_dispatcher);
|
||||
extern pascal void GTESetAddress(Word tableId, Pointer pointer) inline(0x2EA0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Timer Functions */
|
||||
extern pascal Word GTEAddTimer(Word numTicks, Pointer callback, Word flags) inline(0x1FA0, tool_dispatcher);
|
||||
extern pascal Word GTERemoveTimer(Word timerID) inline(0x20A0, tool_dispatcher);
|
||||
extern pascal Word GTEStartScript(Word numTicks, Pointer scriptAddr) inline(0x21A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Overlay Functions */
|
||||
extern pascal Word GTESetOverlay(Word top, Word bottom, Pointer procPtr) inline(0x22A0, tool_dispatcher);
|
||||
extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher);
|
||||
extern pascal void GTEUpdateOverlay(Word top, Word bottom, Pointer procPtr) inline(0x2FA0, tool_dispatcher);
|
||||
|
||||
|
||||
/* ReadControl return value bits */
|
||||
#define PAD_KEY_CODE 0x007F
|
||||
#define PAD_BUTTON_B 0x0100
|
||||
#define PAD_BUTTON_A 0x0200
|
||||
#define PAD_KEY_DOWN 0x0400
|
||||
|
||||
/* GTE EngineMode definitions */
|
||||
#define ENGINE_MODE_TWO_LAYER 0x0001
|
||||
#define ENGINE_MODE_DYN_TILES 0x0002
|
||||
#define ENGINE_MODE_BNK0_BUFF 0x0004
|
||||
#define ENGINE_MODE_USER_TOOL 0x8000 /* Communicate if GTE is loaded as a system tool, or a user tool */
|
||||
|
||||
/* GTE Render Flags */
|
||||
#define RENDER_ALT_BG1 0x0001
|
||||
#define RENDER_BG1_HORZ_OFFSET 0x0002
|
||||
#define RENDER_BG1_VERT_OFFSET 0x0004
|
||||
#define RENDER_BG1_ROTATION 0x0008
|
||||
#define RENDER_PER_SCANLINE 0x0010
|
||||
#define RENDER_WITH_SHADOWING 0x0020
|
||||
#define RENDER_SPRITES_SORTED 0x0040
|
||||
|
||||
/* Overlay flags */
|
||||
#define OVERLAY_MASKED 0x0000 /* Overlay has a mask, so the background must be draw first */
|
||||
#define OVERLAY_SOLID 0x8000 /* Overlay covers the scan line and is fully opaque */
|
||||
#define OVERLAY_ABOVE 0x0000 /* Overlay is drawn above scanline sprites */
|
||||
#define OVERLAY_BELOW 0x4000 /* Overlay is drawn below scanline sprites */
|
||||
|
||||
/* GetAddress table IDs */
|
||||
#define scanlineHorzOffset 0x0001
|
||||
#define scanlineHorzOffset2 0x0002
|
||||
|
||||
/* CopyPicToBG1 flags */
|
||||
#define COPY_PIC_NORMAL 0x0000 /* Copy into BG1 buffer in "normal mode" */
|
||||
#define COPY_PIC_SCANLINE 0x0001 /* Copy in a way to support BG1 + RENDER_PER_SCANLINE. */
|
||||
|
||||
/* GTE Tile Constants */
|
||||
#define TILE_PRIORITY_BIT 0x4000 /* Put tile on top of sprite */
|
||||
#define TILE_USER_BIT 0x2000 /* User-defined tile */
|
||||
#define TILE_SOLID_BIT 0x1000 /* Hint bit used in TWO_LAYER_MODE to optimize rendering */
|
||||
#define TILE_DYN_BIT 0x0800 /* Is this a Dynamic Tile? */
|
||||
#define TILE_VFLIP_BIT 0x0400
|
||||
#define TILE_HFLIP_BIT 0x0200
|
||||
#define TILE_ID_MASK 0x01FF
|
||||
#define TILE_CTRL_MASK 0xFE00
|
||||
|
||||
/* GTE Sprite Constants */
|
||||
#define GTE_SPRITE_COMPILED 0x4000
|
||||
#define GTE_SPRITE_HIDE 0x2000
|
||||
#define GTE_SPRITE_16X16 0x1800
|
||||
#define GTE_SPRITE_16X8 0x1000
|
||||
#define GTE_SPRITE_8X16 0x0800
|
||||
#define GTE_SPRITE_8X8 0x0000
|
||||
#define GTE_SPRITE_VFLIP 0x0400
|
||||
#define GTE_SPRITE_HFLIP 0x0200
|
||||
|
||||
/* GTE Sprint Stamp Storage Parameters */
|
||||
#define GTE_VBUFF_STRIDE_BYTES (12 * 4) /* Each line has 4 slots of 16 pixels + 8 buffer pixels */
|
||||
#define GTE_VBUFF_TILE_ROW_BYTES (8 * GTE_VBUFF_STRIDE_BYTES) /* Each row is comprised of 8 lines */
|
||||
#define GTE_VBUFF_TILE_COL_BYTES (4)
|
||||
#define GTE_VBUFF_SPRITE_STEP (GTE_VBUFF_TILE_ROW_BYTES*3) /* Allocate space for 16 rows + 8 rows of buffer */
|
||||
#define GTE_VBUFF_SPRITE_START (GTE_VBUFF_TILE_ROW_BYTES+4) /* Start at an offset so $0000 can be used as an empty value */
|
||||
#define GTE_VBUFF_SLOT_COUNT (48) /* Have space for this many stamps */
|
||||
|
||||
#define GTE_TILE_SIZE_BYTES 128
|
||||
#define GTE_TILE_STORE_WIDTH 41
|
||||
#define GTE_TILE_STORE_HEIGHT 26
|
||||
|
||||
/* Tile helper macros */
|
||||
#define STATIC_TILE(x) _TILE_DATA(x),_TILE_DATA(0),_TILE_DATA(x),_TILE_DATA(0)
|
||||
#define _TILE_DATA(x) _ROW(x),_ROW(x),_ROW(x),_ROW(x),_ROW(x),_ROW(x),_ROW(x),_ROW(x)
|
||||
#define _ROW(x) x,x,x,x
|
||||
#endif /* _GTE_HEADER_INCLUDE_ */
|
11
README.md
11
README.md
|
@ -8,6 +8,8 @@
|
|||
|
||||
The Generic Tile Engine (GTE) project is a tile engine built to exploit the unique hardware capabilities of the Apple IIgs personal computer. It supports the Apple IIgs super hires graphics mode (320x200, 16/256 colors) and provides two full-screen independent scrolling layers along with software sprites. The API and core functionality of the library is inspired by the graphics hardware of the NES/SMS/SNES/Genesis console era.
|
||||
|
||||
An overview of GTE was presented at [KansasFest 2022](http://www.youtube.com/watch?v=2x65JymFklk).
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/lscharen/iigs-game-engine/master/.github/images/armada.gif"/><br/>
|
||||
Parallax scrolling of two full-screen static layers
|
||||
|
@ -21,7 +23,11 @@ Each demo application has a build script that also builds the toolset and copies
|
|||
|
||||
## Dependencies
|
||||
|
||||
GTE uses the [merlin32](https://brutaldeluxe.fr/products/crossdevtools/merlin/) assembler to compile its source into GS/OS OMF files and [Cadius](https://brutaldeluxe.fr/products/crossdevtools/cadius/index.html) to copy those files onto a ProDOS disk image. The paths to these tool can be set in the `package.json` file.
|
||||
* node
|
||||
* merlin32 (1.1.10+)
|
||||
* cadius
|
||||
|
||||
GTE uses the [merlin32](https://brutaldeluxe.fr/products/crossdevtools/merlin/) [1.1.10](https://github.com/digarok/merlin32/releases/tag/v1.1.10) assembler to compile its source into GS/OS OMF files and [Cadius](https://brutaldeluxe.fr/products/crossdevtools/cadius/index.html) to copy those files onto a ProDOS disk image. The paths to these tool can be set in the `package.json` file.
|
||||
|
||||
An empty 2MG disk image is included in `emu/Target.2mg` and is used as the default location for copying demo applications. This image can be mounted in any IIgs emulator.
|
||||
|
||||
|
@ -30,7 +36,6 @@ An empty 2MG disk image is included in `emu/Target.2mg` and is used as the defau
|
|||
Build of demo app in the IIgs Finder
|
||||
</p>
|
||||
|
||||
|
||||
# Documentation
|
||||
|
||||
Please refer to the <a href="https://lscharen.github.io/iigs-game-engine/toolboxref.html">GTE Toolbox documentation</a>.
|
||||
|
@ -47,3 +52,5 @@ Please refer to the <a href="https://lscharen.github.io/iigs-game-engine/toolbox
|
|||
* [Jon Burton / Traveller's Tales / Coding Secrets](https://ttjontt.wixsite.com/gamehut/coding-secrets)
|
||||
* [Lou's Pseudo 3d Page](http://www.extentofthejam.com/pseudo/)
|
||||
* [A Great Old-Timey Game-Programming Hack](https://blog.moertel.com/posts/2013-12-14-great-old-timey-game-programming-hack.html)
|
||||
* [Tilengine: 2D retro graphics](https://www.tilengine.org/)
|
||||
* [ZX Spectrum Ghost 'n Goblins: Graphics Routines](https://www.emix8.org/ggdisasm/)
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
GTETool.SHK=Type(E0),AuxType(8002),VersionCreate(00),MinVersion(87),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
||||
Tool160.SHK=Type(E0),AuxType(8002),VersionCreate(00),MinVersion(B8),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
||||
CCode.SHK=Type(E0),AuxType(8002),VersionCreate(00),MinVersion(9C),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
||||
ChrisV.SHK=Type(E0),AuxType(8002),VersionCreate(00),MinVersion(BC),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
||||
|
|
|
@ -13,6 +13,6 @@ REM Cadius does not overwrite files, so clear the root folder first
|
|||
%CADIUS% CREATEFOLDER %IMAGE% %FOLDER%
|
||||
|
||||
REM Now copy files and folders as needed
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\src\GTETool
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\src\Tool160
|
||||
|
||||
REM Copy in the image assets
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
App
|
||||
main
|
||||
*.root
|
||||
*.sym
|
||||
*.a
|
|
@ -0,0 +1 @@
|
|||
App=Type(B3),AuxType(0000),VersionCreate(70),MinVersion(BE),Access(E3)
|
Binary file not shown.
After Width: | Height: | Size: 847 B |
|
@ -0,0 +1,17 @@
|
|||
echo off
|
||||
|
||||
REM Copy all of the assets into the ProDOS image for emulator testing
|
||||
REM
|
||||
REM Pass the path of the Cadius tool as the first argument (%1)
|
||||
|
||||
set CADIUS="%1"
|
||||
set IMAGE="..\\..\\emu\\Target.2mg"
|
||||
set FOLDER="/GTEDEV/ChrisV"
|
||||
|
||||
REM Cadius does not overwrite files, so clear the root folder first
|
||||
%CADIUS% DELETEFOLDER %IMAGE% %FOLDER%
|
||||
%CADIUS% CREATEFOLDER %IMAGE% %FOLDER%
|
||||
|
||||
REM Now copy files and folders as needed
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\App
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% ..\..\src\Tool160
|
|
@ -0,0 +1,165 @@
|
|||
/* ********************************************************************
|
||||
|
||||
GTE is copyright Lucas Scharenbroich and licensed under the Apache-2.0
|
||||
License.
|
||||
|
||||
The following GTE function definitions are taken from the GTE Toolbox
|
||||
documentation:
|
||||
https://lscharen.github.io/iigs-game-engine/toolboxref.html
|
||||
|
||||
And from the GTE Macros:
|
||||
https://github.com/lscharen/iigs-game-engine/blob/d7be9f1be44748b0180c930b1f90b144cda661ea/macros/GTE.Macs.s
|
||||
|
||||
The contents of this file are a derivite work from GTE intended to
|
||||
ease the process of calling GTE / Tool 160 from ORCA/C and are believed
|
||||
to be permitted under the terms of the Apache-2.0 License.
|
||||
|
||||
********************************************************************* */
|
||||
|
||||
#ifndef _GTE_HEADER_INCLUDE_
|
||||
#define _GTE_HEADER_INCLUDE_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
GTE_IS_SYSTEM_TOOLS_INSTALL is a boolean toggle for controlling what the application assumes about the location of the GTE tool.
|
||||
|
||||
If GTE is installed in System:Tools, GTE_IS_SYSTEM_TOOLS_INSTALL must be defined.
|
||||
Otherwise, GTE_IS_SYSTEM_TOOLS_INSTALL must be undefined.
|
||||
|
||||
This will control which header file is used as well as the calls used to load the tool during application startup.
|
||||
*/
|
||||
// #define GTE_IS_SYSTEM_TOOLS_INSTALL 1
|
||||
|
||||
#ifdef GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
#define tool_dispatcher dispatcher
|
||||
#else
|
||||
#define tool_dispatcher 0xE10008L
|
||||
#endif // GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
|
||||
typedef struct TileMapInfo {
|
||||
Word width;
|
||||
Word height;
|
||||
Pointer tileMapPtr;
|
||||
} TileMapInfo;
|
||||
|
||||
typedef struct ScreenInfo {
|
||||
Word x;
|
||||
Word y;
|
||||
Word width;
|
||||
Word height;
|
||||
} ScreenInfo;
|
||||
|
||||
/* GTE Housekeeping Routines */
|
||||
extern pascal void GTEBootInit(void) inline(0x01A0, tool_dispatcher);
|
||||
extern pascal void GTEStartUp(Word dPageAddr, Word capFlags, Word userID) inline(0x02A0, tool_dispatcher);
|
||||
extern pascal void GTEShutDown(void) inline(0x03A0, tool_dispatcher);
|
||||
extern pascal Word GTEVersion(void) inline(0x04A0, tool_dispatcher);
|
||||
extern pascal void GTEReset(void) inline(0x05A0, tool_dispatcher);
|
||||
extern pascal Word GTEStatus(void) inline(0x06A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Sprite Routines */
|
||||
extern pascal void GTECreateSpriteStamp(Word spriteDescriptor, Word vBuffAddr) inline(0x0FA0, tool_dispatcher);
|
||||
extern pascal void GTEAddSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr, Word x, Word y) inline(0x10A0, tool_dispatcher);
|
||||
extern pascal void GTEMoveSprite(Word spriteSlot, Word x, Word y) inline(0x11A0, tool_dispatcher);
|
||||
extern pascal void GTEUpdateSprite(Word spriteSlot, Word spriteFlags, Word vBuffAddr) inline(0x12A0, tool_dispatcher);
|
||||
extern pascal void GTERemoveSprite(Word spriteSlot) inline(0x13A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Tile Routines */
|
||||
extern pascal void GTELoadTileSet(Word start, Word finish, Pointer tileSetPtr) inline(0x0EA0, tool_dispatcher);
|
||||
extern pascal void GTEFillTileStore(Word tileID) inline(0x25A0, tool_dispatcher);
|
||||
extern pascal void GTESetTile(Word xTile, Word yTile, Word tileID) inline(0x0BA0, tool_dispatcher);
|
||||
extern pascal void GTECopyTileToDynamic(Word tileID, Word dynID) inline(0x15A0, tool_dispatcher);
|
||||
extern pascal Word GTEGetTileAt(Word x, Word y) inline(0x1CA0, tool_dispatcher);
|
||||
extern pascal Pointer GTEGetTileDataAddr() inline(0x24A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Primary Background Routines */
|
||||
extern pascal void GTESetBG0Origin(Word x, Word y) inline(0x0CA0, tool_dispatcher);
|
||||
extern pascal void GTERender(Word flags) inline(0x0DA0, tool_dispatcher);
|
||||
extern pascal void GTERefresh() inline(0x26A0, tool_dispatcher);
|
||||
extern pascal struct TileMapInfo GTEGetBG0TileMapInfo() inline(0x19A0, tool_dispatcher);
|
||||
extern pascal void GTESetBG0TileMapInfo(Word width, Word height, Pointer tileMapPtr) inline(0x1DA0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Secondary Background Routines */
|
||||
extern pascal void GTESetBG1Origin(Word x, Word y) inline(0x1BA0, tool_dispatcher);
|
||||
extern pascal void GTECopyPicToBG1(Word width, Word height, Word stride, Pointer picPtr) inline(0x17A0, tool_dispatcher);
|
||||
extern pascal void GTESetBG1TileMapInfo(Word width, Word height, Pointer tileMapPtr) inline(0x1EA0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Global State Functions */
|
||||
extern pascal void GTESetScreenMode(Word width, Word height) inline(0x0AA0, tool_dispatcher);
|
||||
extern pascal void GTESetPalette(Word palNum, Pointer palettePtr) inline(0x16A0, tool_dispatcher);
|
||||
extern pascal void GTEBindSCBArray(Pointer scbPtr) inline(0x18A0, tool_dispatcher);
|
||||
extern pascal struct ScreenInfo GTEGetScreenInfo() inline(0x1AA0, tool_dispatcher);
|
||||
extern pascal void GTESetBG1Displacement(Word offset) inline(0x27A0, tool_dispatcher);
|
||||
extern pascal void GTESetBG1Rotation(Word rotIndex) inline(0x28A0, tool_dispatcher);
|
||||
extern pascal void GTEClearBG1Buffer(Word value) inline(0x29A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Misc. Functions */
|
||||
extern pascal Word GTEReadControl(void) inline(0x09A0, tool_dispatcher);
|
||||
extern pascal Word GTEGetSeconds(void) inline(0x14A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Timer Functions */
|
||||
extern pascal Word GTEAddTimer(Word numTicks, Pointer callback, Word flags) inline(0x1FA0, tool_dispatcher);
|
||||
extern pascal Word GTERemoveTimer(Word timerID) inline(0x20A0, tool_dispatcher);
|
||||
extern pascal Word GTEStartScript(Word numTicks, Pointer scriptAddr) inline(0x21A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* GTE Overlay Functions */
|
||||
extern pascal Word GTESetOverlay(Word top, Word bottom, Pointer procPtr) inline(0x22A0, tool_dispatcher);
|
||||
extern pascal Word GTEClearOverlay() inline(0x23A0, tool_dispatcher);
|
||||
|
||||
|
||||
/* ReadControl return value bits */
|
||||
#define PAD_BUTTON_B 0x0100
|
||||
#define PAD_BUTTON_A 0x0200
|
||||
#define PAD_KEY_DOWN 0x0400
|
||||
|
||||
/* GTE EngineMode definitions */
|
||||
#define ENGINE_MODE_TWO_LAYER 0x0001
|
||||
#define ENGINE_MODE_DYN_TILES 0x0002
|
||||
#define ENGINE_MODE_BNK0_BUFF 0x0004
|
||||
#define ENGINE_MODE_USER_TOOL 0x8000 /* Communicate if GTE is loaded as a system tool, or a user tool */
|
||||
|
||||
/* GTE Render Flags */
|
||||
#define RENDER_ALT_BG1 0x0001
|
||||
#define RENDER_BG1_HORZ_OFFSET 0x0002
|
||||
#define RENDER_BG1_VERT_OFFSET 0x0004
|
||||
#define RENDER_BG1_ROTATION 0x0008
|
||||
|
||||
/* GTE Tile Constants */
|
||||
#define TILE_PRIORITY_BIT 0x4000 /* Put tile on top of sprite */
|
||||
#define TILE_FRINGE_BIT 0x2000 /* Unused */
|
||||
#define TILE_SOLID_BIT 0x1000 /* Hint bit used in TWO_LAYER_MODE to optimize rendering */
|
||||
#define TILE_DYN_BIT 0x0800 /* Is this a Dynamic Tile? */
|
||||
#define TILE_VFLIP_BIT 0x0400
|
||||
#define TILE_HFLIP_BIT 0x0200
|
||||
#define TILE_ID_MASK 0x01FF
|
||||
#define TILE_CTRL_MASK 0xFE00
|
||||
|
||||
/* GTE Sprite Constants */
|
||||
#define GTE_SPRITE_HIDE 0x2000
|
||||
#define GTE_SPRITE_16X16 0x1800
|
||||
#define GTE_SPRITE_16X8 0x1000
|
||||
#define GTE_SPRITE_8X16 0x0800
|
||||
#define GTE_SPRITE_8X8 0x0000
|
||||
#define GTE_SPRITE_VFLIP 0x0400
|
||||
#define GTE_SPRITE_HFLIP 0x0200
|
||||
|
||||
|
||||
/* GTE Sprint Stamp Storage Parameters */
|
||||
#define GTE_VBUFF_STRIDE_BYTES (12 * 4) /* Each line has 4 slots of 16 pixels + 8 buffer pixels */
|
||||
#define GTE_VBUFF_TILE_ROW_BYTES (8 * GTE_VBUFF_STRIDE_BYTES) /* Each row is comprised of 8 lines */
|
||||
#define GTE_VBUFF_TILE_COL_BYTES (4)
|
||||
#define GTE_VBUFF_SPRITE_STEP (GTE_VBUFF_TILE_ROW_BYTES*3) /* Allocate space for 16 rows + 8 rows of buffer */
|
||||
#define GTE_VBUFF_SPRITE_START (GTE_VBUFF_TILE_ROW_BYTES+4) /* Start at an offset so $0000 can be used as an empty value */
|
||||
#define GTE_VBUFF_SLOT_COUNT (48) /* Have space for this many stamps */
|
||||
|
||||
|
||||
#endif /* _GTE_HEADER_INCLUDE_ */
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "chrisv-c-demo",
|
||||
"version": "1.0.0",
|
||||
"description": "Using GTE from C",
|
||||
"main": "index.js",
|
||||
"config": {
|
||||
"merlin32": "C:\\Programs\\IIgsXDev\\bin\\Merlin32-1.1.10.exe",
|
||||
"cadius": "C:\\Programs\\IIgsXDev\\bin\\Cadius.exe",
|
||||
"gsport": "C:\\Programs\\gsport\\gsport_0.31\\GSPort.exe",
|
||||
"macros": "../../macros",
|
||||
"crossrunner": "C:\\Programs\\Crossrunner\\Crossrunner.exe",
|
||||
"png2iigs": "../../tools/png2iigs.js"
|
||||
},
|
||||
"scripts": {
|
||||
"gsport": "%npm_package_config_gsport%",
|
||||
"test:all": "npm run build && npm run build:image && %npm_package_config_gsport%",
|
||||
"build": "npm run build:tool && npm run build:sys16",
|
||||
"test": "npm run build:sys16 && npm run build:image && %npm_package_config_gsport%",
|
||||
"build:image": "build-image.bat %npm_package_config_cadius%",
|
||||
"build:sys16": "iix compile foo.c test.c && iix -DKeepType=S16 link test foo keep=App",
|
||||
"build:tiles": "node %npm_package_config_png2iigs% ./assets/tileset.png --format orcac --max-tiles 160 --as-tile-data --verbose > tileData.c",
|
||||
"build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../src/Master.s",
|
||||
"debug": "%npm_package_config_crossrunner% ./App -Debug -CompatibilityLayer"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
#include <loader.h>
|
||||
#include <locator.h>
|
||||
#include <memory.h>
|
||||
#include <misctool.h>
|
||||
#include <types.h>
|
||||
|
||||
/* #define GTE_IS_SYSTEM_TOOLS_INSTALL 1 */
|
||||
#include "gte.h"
|
||||
|
||||
#ifdef GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
#define ENGINE_STARTUP_MODE 0x0000
|
||||
#else
|
||||
#define ENGINE_STARTUP_MODE ENGINE_MODE_USER_TOOL
|
||||
#endif
|
||||
|
||||
/* toolbox fail handler */
|
||||
#define TOOLFAIL(string) if (toolerror()) SysFailMgr(toolerror(), "\p" string "\n\r Error Code -> $");
|
||||
|
||||
/* path to the local GTE toolset */
|
||||
Str32 toolPath = {9, "1/Tool160" };
|
||||
|
||||
/* Helper function to load GTE as a user tool or system tool */
|
||||
#ifdef GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
void LoadGTEToolSet(Word unused) {
|
||||
LoadOneTool(160, 0);
|
||||
TOOLFAIL("Unable to load GTE toolset");
|
||||
}
|
||||
#else
|
||||
void LoadGTEToolSet(Word userId) {
|
||||
InitialLoadOutputRec loadRec;
|
||||
|
||||
// Load the tool from the local directory
|
||||
loadRec = InitialLoad(userId, (Pointer) (&toolPath), 1);
|
||||
TOOLFAIL("Unable to load Tool160 from local path");
|
||||
|
||||
// Install the tool using the user tool vector
|
||||
SetTSPtr(0x8000, 160, loadRec.startAddr);
|
||||
TOOLFAIL("Could not install tool");
|
||||
}
|
||||
#endif // GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
|
||||
#ifdef GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
void UnloadGTEToolSet() {
|
||||
UnloadOneTool(160);
|
||||
TOOLFAIL("Unable to unload GTE toolset");
|
||||
}
|
||||
#else
|
||||
void UnloadGTEToolSet() {
|
||||
}
|
||||
#endif // GTE_IS_SYSTEM_TOOLS_INSTALL
|
||||
|
||||
extern Byte tiles[];
|
||||
extern Word tilesPalette[16];
|
||||
|
||||
void main(void) {
|
||||
Word userId;
|
||||
Word tileId;
|
||||
Word controlMask, keyPress;
|
||||
Handle dpHandle;
|
||||
Word dpAddr;
|
||||
int a, b;
|
||||
|
||||
TLStartUp();
|
||||
TOOLFAIL("Unable to start tool locator");
|
||||
|
||||
userId = MMStartUp();
|
||||
TOOLFAIL("Unable to start memory manager");
|
||||
|
||||
MTStartUp();
|
||||
TOOLFAIL("Unable to start misc tools");
|
||||
|
||||
LoadGTEToolSet(userId);
|
||||
|
||||
dpHandle = NewHandle(0x200L, userId, attrBank + attrPage + attrFixed + attrLocked + attrNoCross, 0);
|
||||
TOOLFAIL("Could not allocate direct page memory for GTE");
|
||||
dpAddr = (Word) (*dpHandle);
|
||||
|
||||
GTEStartUp(dpAddr, (Word) ENGINE_STARTUP_MODE, userId);
|
||||
|
||||
/* GTESetScreenMode(160, 200); /* 160x200 is the default screen mode */
|
||||
GTESetPalette(0, (Pointer)tilesPalette);
|
||||
GTELoadTileSet(0, 160, tiles); /* Load in the tiles */
|
||||
|
||||
GTEFillTileStore(1);
|
||||
GTERender(0);
|
||||
|
||||
for (a = 3; a < 18; a++) {
|
||||
GTESetTile(a, a, 5);
|
||||
}
|
||||
GTESetTile(1, 0, 34);
|
||||
GTESetTile(2, 0, 33);
|
||||
GTERender(0);
|
||||
|
||||
GTESetTile(0, 3, 3);
|
||||
GTESetTile(0, 4, 4);
|
||||
for (b = 4; b < 6; b++) {
|
||||
for (a = 1; a < 10; a++) {
|
||||
GTESetBG0Origin(a, b);
|
||||
tileId = (((b - 1) * 32) + a) | TILE_SOLID_BIT | TILE_HFLIP_BIT;
|
||||
GTESetTile(a, b, tileId);
|
||||
GTERender(0);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
controlMask = GTEReadControl();
|
||||
keyPress = controlMask & 0x007F;
|
||||
} while (keyPress != 'Q');
|
||||
|
||||
GTEShutDown();
|
||||
UnloadGTEToolSet();
|
||||
|
||||
DisposeHandle(dpHandle);
|
||||
MTShutDown();
|
||||
MMShutDown(userId);
|
||||
TLShutDown();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -35,8 +35,19 @@ MaxGlobalX equ 16
|
|||
MaxGlobalY equ 18
|
||||
MaxBG0X equ 20
|
||||
MaxBG0Y equ 22
|
||||
frameCount equ 24
|
||||
OldOneSecondCounter equ 26
|
||||
appTmp0 equ 28
|
||||
seg1x equ 30
|
||||
seg2x equ 32
|
||||
seg3x equ 34
|
||||
seg4x equ 36 ; BG1 x-pos
|
||||
frameCountTotal equ 38
|
||||
PlayerX equ 40
|
||||
PlayerY equ 42
|
||||
PlayerXVel equ 44
|
||||
PlayerYVel equ 46
|
||||
OverlayTop equ 48
|
||||
|
||||
phk
|
||||
plb
|
||||
|
@ -47,23 +58,19 @@ appTmp0 equ 28
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #0 ; Engine in Fast Mode
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER ; Engine in Fast Mode as a User Tool
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
||||
stz StartX
|
||||
stz StartY
|
||||
stz frameCount
|
||||
|
||||
; Initialize the graphics screen playfield
|
||||
|
||||
pea #320
|
||||
pea #160
|
||||
pea #200
|
||||
_GTESetScreenMode
|
||||
|
||||
; Load a tileset
|
||||
|
||||
pea 0
|
||||
pea 256
|
||||
pea #^tiledata
|
||||
pea #tiledata
|
||||
_GTELoadTileSet
|
||||
|
@ -73,10 +80,39 @@ appTmp0 equ 28
|
|||
pea #TileSetPalette
|
||||
_GTESetPalette
|
||||
|
||||
pea $0
|
||||
_GTEClearBG1Buffer
|
||||
|
||||
; Set up our level data
|
||||
|
||||
jsr BG0SetUp
|
||||
; jsr BG0SetUp
|
||||
pea 416
|
||||
pea 30
|
||||
pea ^App_TileMapBG0
|
||||
pea App_TileMapBG0+{10*416}
|
||||
_GTESetBG0TileMapInfo
|
||||
|
||||
stz seg1x
|
||||
stz seg2x
|
||||
stz seg3x
|
||||
stz seg4x
|
||||
|
||||
jsr SetLimits
|
||||
jsr DoLoadBG1
|
||||
|
||||
; Initialize local variables
|
||||
|
||||
lda #56
|
||||
sta StartX
|
||||
lda #0
|
||||
sta StartY
|
||||
stz frameCount
|
||||
stz frameCountTotal
|
||||
stz OverlayTop
|
||||
|
||||
pei StartX
|
||||
pei StartY
|
||||
_GTESetBG0Origin
|
||||
|
||||
lda #193 ; Tile ID of '0'
|
||||
jsr InitOverlay ; Initialize the status bar
|
||||
|
@ -86,6 +122,59 @@ appTmp0 equ 28
|
|||
sta OldOneSecondCounter
|
||||
jsr UdtOverlay
|
||||
|
||||
; Create some sprites
|
||||
lda #16
|
||||
sta PlayerX
|
||||
|
||||
lda MaxGlobalY
|
||||
sec
|
||||
sbc #48 ; 32 for tiles, 16 for sprite
|
||||
lda #48 ; 32 for tiles, 16 for sprite
|
||||
sta PlayerY
|
||||
stz PlayerXVel
|
||||
stz PlayerYVel
|
||||
|
||||
HERO_SIZE equ {SPRITE_16X16}
|
||||
HERO_FLAGS equ HERO_SIZE ; no extra H/V bits for now
|
||||
HERO_FRAME_1 equ HERO_SIZE+145
|
||||
HERO_VBUFF_1 equ VBUFF_SPRITE_START+0*VBUFF_SPRITE_STEP
|
||||
HERO_SLOT equ 1
|
||||
|
||||
pea HERO_FRAME_1
|
||||
pea HERO_VBUFF_1
|
||||
_GTECreateSpriteStamp
|
||||
|
||||
pha ; Space for result
|
||||
pea HERO_SIZE
|
||||
pea HERO_VBUFF_1
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
|
||||
pea HERO_SLOT ; Put the player in slot 1
|
||||
pea HERO_FLAGS+SPRITE_COMPILED ; mark this as a compiled sprite (can only use in RENDER_WITH_SHADOWING mode)
|
||||
pha ; pass in the token of the compiled stamp
|
||||
pei PlayerX
|
||||
pei PlayerY
|
||||
_GTEAddSprite
|
||||
|
||||
; Set up the per-scanline rendering
|
||||
|
||||
lda StartX
|
||||
jsr InitOffsets
|
||||
|
||||
pea #scanlineHorzOffset
|
||||
pea #^BG0Offsets
|
||||
pea #BG0Offsets
|
||||
_GTESetAddress
|
||||
|
||||
pea #scanlineHorzOffset2
|
||||
pea #^BG1Offsets
|
||||
pea #BG1Offsets
|
||||
_GTESetAddress
|
||||
|
||||
pea #RENDER_WITH_SHADOWING ; one regular render to fill the screen with the tilemap
|
||||
_GTERender
|
||||
|
||||
; Set up a very specific test. First, we draw a sprite into the sprite plane, and then
|
||||
; leave it alone. We are just testing the ability to merge sprite plane data into
|
||||
; the play field tiles.
|
||||
|
@ -101,26 +190,15 @@ EvtLoop
|
|||
:do_more
|
||||
cmp #'d'
|
||||
bne :not_d
|
||||
lda StartX
|
||||
cmp MaxBG0X
|
||||
bcc *+5
|
||||
brl :do_render
|
||||
inc StartX
|
||||
pei StartX
|
||||
pei StartY
|
||||
_GTESetBG0Origin
|
||||
jsr DecRanges
|
||||
jsr SetOffsets
|
||||
brl :do_render
|
||||
:not_d
|
||||
|
||||
cmp #'a'
|
||||
bne :not_a
|
||||
lda StartX
|
||||
bne *+5
|
||||
brl :do_render
|
||||
dec StartX
|
||||
pei StartX
|
||||
pei StartY
|
||||
_GTESetBG0Origin
|
||||
jsr IncRanges
|
||||
jsr SetOffsets
|
||||
brl :do_render
|
||||
:not_a
|
||||
|
||||
|
@ -146,14 +224,43 @@ EvtLoop
|
|||
_GTESetBG0Origin
|
||||
bra :do_render
|
||||
:not_w
|
||||
cmp #' '
|
||||
bne :not_space
|
||||
lda OverlayTop
|
||||
inc
|
||||
and #$3F
|
||||
sta OverlayTop
|
||||
pha
|
||||
clc
|
||||
adc #8
|
||||
pha
|
||||
pea #^StatusBar
|
||||
pea #StatusBar
|
||||
_GTEUpdateOverlay
|
||||
|
||||
:not_space
|
||||
:do_render
|
||||
pea $0000
|
||||
jsr SetBG1Animation ; Update the per-scanline BG1 offsets
|
||||
|
||||
jsr _GetVBLTicks
|
||||
and #$00FC
|
||||
lsr
|
||||
lsr
|
||||
sta PlayerX
|
||||
|
||||
pea HERO_SLOT
|
||||
pei PlayerX
|
||||
pei PlayerY
|
||||
_GTEMoveSprite ; Move the sprite to this local position
|
||||
|
||||
pea #RENDER_PER_SCANLINE
|
||||
; pea #0
|
||||
_GTERender
|
||||
|
||||
; Update the performance counters
|
||||
|
||||
inc frameCount
|
||||
inc frameCountTotal
|
||||
pha
|
||||
_GTEGetSeconds
|
||||
pla
|
||||
|
@ -180,6 +287,13 @@ qtRec adrl $0000
|
|||
; Color palette
|
||||
MyDirectPage ds 2
|
||||
|
||||
_GetVBLTicks
|
||||
PushLong #0
|
||||
_GetTick
|
||||
pla
|
||||
plx
|
||||
rts
|
||||
|
||||
SetLimits
|
||||
pha ; Allocate space for width (in tiles), height (in tiles), pointer
|
||||
pha
|
||||
|
@ -238,7 +352,211 @@ SetLimits
|
|||
|
||||
rts
|
||||
|
||||
frameCount equ 24
|
||||
DecRanges
|
||||
lda seg1x
|
||||
bne *+5
|
||||
lda #164
|
||||
dec
|
||||
sta seg1x
|
||||
bit #1
|
||||
bne :out
|
||||
lda seg2x
|
||||
bne *+5
|
||||
lda #164
|
||||
dec
|
||||
sta seg2x
|
||||
bit #1
|
||||
bne :out
|
||||
lda seg3x
|
||||
bne *+5
|
||||
lda #164
|
||||
dec
|
||||
sta seg3x
|
||||
:out
|
||||
rts
|
||||
|
||||
IncRanges
|
||||
lda seg1x
|
||||
inc
|
||||
cmp #164
|
||||
bcc *+5
|
||||
lda #0
|
||||
sta seg1x
|
||||
bit #1
|
||||
bne :out
|
||||
lda seg2x
|
||||
inc
|
||||
cmp #164
|
||||
bcc *+5
|
||||
lda #0
|
||||
sta seg2x
|
||||
bit #1
|
||||
bne :out
|
||||
lda seg3x
|
||||
inc
|
||||
cmp #164
|
||||
bcc *+5
|
||||
lda #0
|
||||
sta seg3x
|
||||
bit #1
|
||||
bne :out
|
||||
lda seg4x
|
||||
inc
|
||||
cmp #164
|
||||
bcc *+5
|
||||
lda #0
|
||||
sta seg4x
|
||||
:out
|
||||
rts
|
||||
|
||||
|
||||
InitOffsets
|
||||
pha
|
||||
|
||||
ldx #0
|
||||
ldy #40
|
||||
jsr _InitRange
|
||||
ldx #40
|
||||
ldy #80
|
||||
jsr _InitRange
|
||||
ldx #120
|
||||
ldy #88
|
||||
jsr _InitRange
|
||||
jsr _InitBG1
|
||||
|
||||
pla
|
||||
sta seg1x
|
||||
jsr SetOffset1
|
||||
lsr
|
||||
sta seg2x
|
||||
jsr SetOffset2
|
||||
lsr
|
||||
sta seg3x
|
||||
jsr SetOffset3
|
||||
jsr SetBG1Offsets
|
||||
rts
|
||||
|
||||
SetOffsets
|
||||
lda seg1x
|
||||
jsr SetOffset1
|
||||
lda seg2x
|
||||
jsr SetOffset2
|
||||
lda seg3x
|
||||
jsr SetOffset3
|
||||
|
||||
SetBG1Offsets
|
||||
pei seg4x
|
||||
pea 0
|
||||
_GTESetBG1Origin
|
||||
rts
|
||||
|
||||
SetBG1Animation
|
||||
pea #scanlineHorzOffset2
|
||||
pea #^BG1Offsets
|
||||
lda frameCountTotal
|
||||
and #$000F
|
||||
asl
|
||||
adc #BG1Offsets
|
||||
pha
|
||||
_GTESetAddress
|
||||
rts
|
||||
|
||||
SetOffset1
|
||||
ldx #120
|
||||
ldy #88
|
||||
jmp _SetRange
|
||||
SetOffset2
|
||||
ldx #40
|
||||
ldy #80
|
||||
jmp _SetRange
|
||||
SetOffset3
|
||||
ldx #0
|
||||
ldy #40
|
||||
jmp _SetRange
|
||||
|
||||
_SetRange
|
||||
pha
|
||||
|
||||
txa
|
||||
asl
|
||||
tax
|
||||
|
||||
:loop2 lda BG0Offsets,x
|
||||
and #$FF00
|
||||
ora 1,s
|
||||
sta BG0Offsets,x
|
||||
|
||||
dey
|
||||
beq :done
|
||||
|
||||
inx
|
||||
inx
|
||||
cpx #416
|
||||
bcc :loop2
|
||||
:done
|
||||
pla
|
||||
rts
|
||||
|
||||
_offsets dw 0,0,0,1,1,2,3,3,4,4,4,3,3,2,1,1
|
||||
_InitBG1
|
||||
ldx #0
|
||||
ldy #0
|
||||
:loop lda _offsets,y
|
||||
sta BG1Offsets,x
|
||||
iny
|
||||
iny
|
||||
cpy #31
|
||||
bcc *+5
|
||||
ldy #0
|
||||
|
||||
inx
|
||||
inx
|
||||
cpx #448
|
||||
bcc :loop
|
||||
rts
|
||||
|
||||
_InitRange
|
||||
txa
|
||||
asl
|
||||
tax
|
||||
|
||||
tya
|
||||
dec
|
||||
and #$00FF
|
||||
xba
|
||||
|
||||
:loop1 sta BG0Offsets,x
|
||||
sec
|
||||
sbc #$0100
|
||||
dey
|
||||
beq :done
|
||||
inx
|
||||
inx
|
||||
cpx #416
|
||||
bcc :loop1
|
||||
:done
|
||||
rts
|
||||
|
||||
; Load a binary file in the BG1 buffer
|
||||
DoLoadBG1
|
||||
jsr AllocBank ; Alloc 64KB for Load/Unpack
|
||||
sta BankLoad ; Store "Bank Pointer"
|
||||
ldx #BG1DataFile ; Load the background file into the bank
|
||||
jsr LoadFile
|
||||
|
||||
pea #164 ; Fill everything
|
||||
pea #200
|
||||
pea #256
|
||||
lda BankLoad
|
||||
pha
|
||||
pea $0000
|
||||
pea COPY_PIC_SCANLINE ; Copy in a mode that supports per-scanline offsets
|
||||
_GTECopyPicToBG1
|
||||
rts
|
||||
|
||||
BG1DataFile strl '1/bg1.bin'
|
||||
BG0Offsets ds 416
|
||||
BG1Offsets ds 448 ; Make this a bit larger so we can just update a pointer
|
||||
|
||||
PUT ../StartUp.s
|
||||
PUT ../../shell/Overlay.s
|
||||
|
|
|
@ -14,4 +14,5 @@ REM Cadius does not overwrite files, so clear the root folder first
|
|||
|
||||
REM Now copy files and folders as needed
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\GTEDemo1
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\gen\bg1.bin
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% ..\..\..\src\Tool160
|
||||
|
|
Binary file not shown.
|
@ -61,7 +61,7 @@ Scale equ 56
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_TWO_LAYER+ENGINE_MODE_DYN_TILES
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER ; +ENGINE_MODE_DYN_TILES
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
|
|
@ -47,7 +47,7 @@ appTmp0 equ 28
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_DYN_TILES ; Engine in Fast Mode
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_DYN_TILES ; Engine in Fast Mode
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
|
|
@ -56,7 +56,7 @@ appTmp2 equ 32
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_DYN_TILES ; Engine in Fast Mode
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_DYN_TILES ; Engine in Fast Mode
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
|
|
@ -49,7 +49,7 @@ appTmp2 equ 32
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_TWO_LAYER+ENGINE_MODE_DYN_TILES
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER ; +ENGINE_MODE_DYN_TILES
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
@ -60,12 +60,14 @@ appTmp2 equ 32
|
|||
|
||||
; Initialize the graphics screen playfield
|
||||
|
||||
pea #320
|
||||
pea #160
|
||||
pea #200
|
||||
_GTESetScreenMode
|
||||
|
||||
; Load a tileset
|
||||
|
||||
pea #0
|
||||
pea #511
|
||||
pea #^tiledata
|
||||
pea #tiledata
|
||||
_GTELoadTileSet
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,17 +14,17 @@
|
|||
},
|
||||
"scripts": {
|
||||
"test": "npm run build && npm run build:image && npm run gsport",
|
||||
"gsport": "%npm_package_config_gsport%",
|
||||
"debug": "%npm_package_config_crossrunner% GTEDemo4 -Source GTEDemo4_S02_MAINSEG_Output.txt -Debug -CompatibilityLayer",
|
||||
"gsport": "cross-var $npm_package_config_gsport",
|
||||
"debug": "cross-var $npm_package_config_crossrunner GTEDemo4 -Source GTEDemo4_S02_MAINSEG_Output.txt -Debug -CompatibilityLayer",
|
||||
"build:all": "npm run build:tiles && npm run build:map && npm run build:tool && npm run build:sys16 && npm run build:image",
|
||||
"build:map": "node %npm_package_config_tiled2iigs% ./assets/tiled/yoshi-1.json --force-masked --no-gen-tiles --output-dir ./gen",
|
||||
"build:tiles": "node %npm_package_config_png2iigs% ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --verbose --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:tiles:blocky": "node %npm_package_config_png2iigs% ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --verbose --force-word-alignment --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:sys16": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s",
|
||||
"build:map": "cross-var node $npm_package_config_tiled2iigs ./assets/tiled/yoshi-1.json --force-masked --no-gen-tiles --output-dir ./gen",
|
||||
"build:tiles": "cross-var node $npm_package_config_png2iigs ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --var-name tiledata --verbose --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:tiles:blocky": "cross-var node $npm_package_config_png2iigs ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --var-name tiledata --verbose --force-word-alignment --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:sys16": "cross-var $npm_package_config_merlin32 -V $npm_package_config_macros App.s",
|
||||
"build": "npm run build:tool && npm run build:sys16",
|
||||
"build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../../src/Master.s",
|
||||
"build:image": "build-image.bat %npm_package_config_cadius%",
|
||||
"build:background": "node %npm_package_config_png2iigs% ./assets/tilesets/bg1.png ./gen/bg1.bin --force-color-match --palette FF00FF,C14F4A,020202,00E100,C89858,216058,DCE9EE,008000,F80080,F5D56C,20308F,A0CDCC,4080A0,70B0D0"
|
||||
"build:tool": "cross-var $npm_package_config_merlin32 -V $npm_package_config_macros ../../../src/Master.s",
|
||||
"build:image": "cross-var build-image.bat $npm_package_config_cadius",
|
||||
"build:background": "cross-var node $npm_package_config_png2iigs ./assets/tilesets/bg1.png ./gen/bg1.bin --force-color-match --palette FF00FF,C14F4A,020202,00E100,C89858,216058,DCE9EE,008000,F80080,F5D56C,20308F,A0CDCC,4080A0,70B0D0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -37,6 +37,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/lscharen/iigs-game-engine#readme",
|
||||
"devDependencies": {
|
||||
"cross-var": "^1.1.0",
|
||||
"pngjs": "^6.0.0",
|
||||
"string-builder": "^0.1.8",
|
||||
"watch": "latest",
|
||||
|
|
|
@ -36,6 +36,7 @@ MaxGlobalX equ 16
|
|||
MaxGlobalY equ 18
|
||||
MaxBG0X equ 20
|
||||
MaxBG0Y equ 22
|
||||
frameCount equ 24
|
||||
OldOneSecondCounter equ 26
|
||||
appTmp0 equ 28
|
||||
PlayerX equ 30
|
||||
|
@ -49,6 +50,10 @@ LastHFlip equ 44
|
|||
SpriteFrame equ 46
|
||||
SpriteToggle equ 48
|
||||
SpriteCount equ 50
|
||||
PlayerX1 equ 52
|
||||
PlayerY1 equ 54
|
||||
PlayerX2 equ 56
|
||||
PlayerY2 equ 58
|
||||
|
||||
phk
|
||||
plb
|
||||
|
@ -59,10 +64,11 @@ SpriteCount equ 50
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #0 ; Engine in Fast Mode
|
||||
lda #ENGINE_MODE_USER_TOOL ; Engine in Fast Mode
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
jsr SoundStartUp
|
||||
jsr StartMusic
|
||||
|
||||
; jsr SoundStartUp
|
||||
; jsr StartMusic
|
||||
|
||||
; Initialize local variables
|
||||
|
||||
|
@ -75,12 +81,14 @@ SpriteCount equ 50
|
|||
|
||||
; Initialize the graphics screen playfield
|
||||
|
||||
pea #320
|
||||
pea #200
|
||||
pea #160 ; width in bytes
|
||||
pea #200 ; height in lines
|
||||
_GTESetScreenMode
|
||||
|
||||
; Load a tileset
|
||||
|
||||
pea #0
|
||||
pea #511
|
||||
pea #^tiledata
|
||||
pea #tiledata
|
||||
_GTELoadTileSet
|
||||
|
@ -108,27 +116,44 @@ SpriteCount equ 50
|
|||
lda #16
|
||||
sta PlayerGlobalX
|
||||
sta PlayerX
|
||||
sta PlayerX1
|
||||
sta PlayerX2
|
||||
|
||||
lda MaxGlobalY
|
||||
sec
|
||||
sbc #48 ; 32 for tiles, 16 for sprite
|
||||
lda #48 ; 32 for tiles, 16 for sprite
|
||||
sta PlayerGlobalY
|
||||
sta PlayerY
|
||||
sta PlayerY1
|
||||
sta PlayerY2
|
||||
|
||||
stz PlayerXVel
|
||||
stz PlayerYVel
|
||||
|
||||
; Set the screen to the bottom-left
|
||||
|
||||
pea $0000
|
||||
lda MaxBG0Y
|
||||
pha
|
||||
_GTESetBG0Origin
|
||||
|
||||
; Create the sprites
|
||||
|
||||
HERO_FRAME_1 equ {SPRITE_16X16+145}
|
||||
HERO_SIZE equ {SPRITE_16X16}
|
||||
HERO_FLAGS equ HERO_SIZE ; no extra H/V bits for now
|
||||
HERO_FRAME_1 equ HERO_SIZE+145
|
||||
HERO_VBUFF_1 equ VBUFF_SPRITE_START+0*VBUFF_SPRITE_STEP
|
||||
HERO_FRAME_2 equ {SPRITE_16X16+147}
|
||||
HERO_FRAME_2 equ HERO_SIZE+147
|
||||
HERO_VBUFF_2 equ VBUFF_SPRITE_START+1*VBUFF_SPRITE_STEP
|
||||
HERO_FRAME_3 equ {SPRITE_16X16+149}
|
||||
HERO_FRAME_3 equ HERO_SIZE+149
|
||||
HERO_VBUFF_3 equ VBUFF_SPRITE_START+2*VBUFF_SPRITE_STEP
|
||||
HERO_FRAME_4 equ {SPRITE_16X16+151}
|
||||
HERO_FRAME_4 equ HERO_SIZE+151
|
||||
HERO_VBUFF_4 equ VBUFF_SPRITE_START+3*VBUFF_SPRITE_STEP
|
||||
HERO_SLOT equ 1
|
||||
|
||||
; Create stamps of each sprite
|
||||
|
||||
pea HERO_FRAME_1
|
||||
pea HERO_VBUFF_1
|
||||
_GTECreateSpriteStamp
|
||||
|
@ -145,16 +170,38 @@ HERO_SLOT equ 1
|
|||
pea HERO_VBUFF_4
|
||||
_GTECreateSpriteStamp
|
||||
|
||||
pea HERO_FRAME_1
|
||||
; Compile the sprite stamps and hold the compilation token
|
||||
|
||||
pha ; Space for result
|
||||
pea HERO_SIZE
|
||||
pea HERO_VBUFF_1
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
|
||||
pea HERO_SLOT ; Put the player in slot 1
|
||||
pea HERO_FLAGS+SPRITE_COMPILED ; mark this as a compiled sprite (can only use in RENDER_WITH_SHADOWING mode)
|
||||
pha ; pass in the token of the compiled stamp
|
||||
pei PlayerX
|
||||
pei PlayerY
|
||||
pea HERO_SLOT ; Put the player in slot 1
|
||||
_GTEAddSprite
|
||||
|
||||
pea HERO_SLOT
|
||||
pea $0000
|
||||
; brl Exit
|
||||
|
||||
; Repeat for each stamp. _GTECompileSpriteStamp will return an error if it runs out of memory
|
||||
|
||||
pea HERO_SLOT+1 ; Put the player in slot 1
|
||||
pea HERO_FLAGS
|
||||
pea HERO_VBUFF_1 ; and use this stamp
|
||||
_GTEUpdateSprite
|
||||
pei PlayerX1
|
||||
pei PlayerY1
|
||||
_GTEAddSprite
|
||||
|
||||
pea HERO_SLOT+2 ; Put the player in slot 1
|
||||
pea HERO_FLAGS
|
||||
pea HERO_VBUFF_1 ; and use this stamp
|
||||
pei PlayerX2
|
||||
pei PlayerY2
|
||||
_GTEAddSprite
|
||||
|
||||
EvtLoop
|
||||
pha
|
||||
|
@ -209,7 +256,30 @@ do_render
|
|||
pei PlayerY
|
||||
_GTEMoveSprite ; Move the sprite to this local position
|
||||
|
||||
pea $0000
|
||||
pea HERO_SLOT+1
|
||||
lda PlayerX1
|
||||
sec
|
||||
sbc StartX
|
||||
pha
|
||||
lda PlayerY1
|
||||
sec
|
||||
sbc StartY
|
||||
pha
|
||||
_GTEMoveSprite ; Move the sprite to this local position
|
||||
|
||||
pea HERO_SLOT+2
|
||||
lda PlayerX2
|
||||
sec
|
||||
sbc StartX
|
||||
pha
|
||||
lda PlayerY2
|
||||
sec
|
||||
sbc StartY
|
||||
pha
|
||||
_GTEMoveSprite ; Move the sprite to this local position
|
||||
|
||||
pea #RENDER_WITH_SHADOWING
|
||||
; pea $0000
|
||||
_GTERender
|
||||
|
||||
; Update the performance counters
|
||||
|
@ -228,7 +298,7 @@ do_render
|
|||
|
||||
; Exit code
|
||||
Exit
|
||||
jsr SoundShutDown
|
||||
; jsr SoundShutDown
|
||||
_GTEShutDown
|
||||
Quit
|
||||
_QuitGS qtRec
|
||||
|
@ -385,6 +455,17 @@ UpdatePlayerPos
|
|||
|
||||
ApplyCollisions
|
||||
|
||||
; Move coordinates down the list
|
||||
lda PlayerX1
|
||||
sta PlayerX2
|
||||
lda PlayerY1
|
||||
sta PlayerY2
|
||||
|
||||
lda PlayerGlobalX
|
||||
sta PlayerX1
|
||||
lda PlayerGlobalY
|
||||
sta PlayerY1
|
||||
|
||||
; Convert global to local coordinates
|
||||
|
||||
lda PlayerGlobalX
|
||||
|
@ -470,10 +551,10 @@ ApplyCollisions
|
|||
tax
|
||||
:frame
|
||||
|
||||
pea HERO_SLOT
|
||||
pei LastHFlip
|
||||
phx
|
||||
_GTEUpdateSprite
|
||||
; pea HERO_SLOT
|
||||
; pei LastHFlip
|
||||
; phx
|
||||
; _GTEUpdateSprite
|
||||
|
||||
rts
|
||||
|
||||
|
@ -527,8 +608,6 @@ _GetVBLTicks
|
|||
plx
|
||||
rts
|
||||
|
||||
frameCount equ 24
|
||||
|
||||
MusicFile str '1/overworld.ntp'
|
||||
|
||||
PUT ../StartUp.s
|
||||
|
|
|
@ -49,7 +49,7 @@ appTmp2 equ 32
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_TWO_LAYER+ENGINE_MODE_DYN_TILES
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER+ENGINE_MODE_DYN_TILES
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
|
|
@ -60,7 +60,7 @@ SpriteCount equ 54
|
|||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_TWO_LAYER+ENGINE_MODE_DYN_TILES
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER ; +ENGINE_MODE_DYN_TILES
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Initialize local variables
|
||||
|
@ -75,12 +75,14 @@ SpriteCount equ 54
|
|||
|
||||
; Initialize the graphics screen playfield
|
||||
|
||||
pea #320
|
||||
pea #160
|
||||
pea #200
|
||||
_GTESetScreenMode
|
||||
|
||||
; Load a tileset
|
||||
|
||||
pea #0
|
||||
pea #511
|
||||
pea #^tiledata
|
||||
pea #tiledata
|
||||
_GTELoadTileSet
|
||||
|
@ -141,6 +143,8 @@ SpriteCount equ 54
|
|||
|
||||
; Create the sprites
|
||||
|
||||
HERO_SIZE equ {SPRITE_16X16}
|
||||
HERO_FLAGS equ HERO_SIZE ; no extra H/V bits for now
|
||||
HERO_FRAME_1 equ {SPRITE_16X16+1}
|
||||
HERO_VBUFF_1 equ VBUFF_SPRITE_START+0*VBUFF_SPRITE_STEP
|
||||
HERO_FRAME_2 equ {SPRITE_16X16+7}
|
||||
|
@ -168,31 +172,71 @@ HERO_SLOT_2 equ 2
|
|||
pea HERO_VBUFF_4
|
||||
_GTECreateSpriteStamp
|
||||
|
||||
pea HERO_FRAME_1
|
||||
DO 0
|
||||
lda #SPRITE_16X16
|
||||
sta SpriteFlags1
|
||||
lda #SPRITE_16X8
|
||||
sta SpriteFlags2
|
||||
ELSE
|
||||
lda #SPRITE_16X16+SPRITE_COMPILED
|
||||
sta SpriteFlags1
|
||||
lda #SPRITE_16X8+SPRITE_COMPILED
|
||||
sta SpriteFlags2
|
||||
|
||||
pha ; Space for result
|
||||
pea HERO_SIZE
|
||||
pea HERO_VBUFF_1
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
sta HeroFrames1+2
|
||||
sta HeroFrames1+6
|
||||
|
||||
pha ; Space for result
|
||||
pea HERO_SIZE
|
||||
pea HERO_VBUFF_2
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
sta HeroFrames1+0
|
||||
sta HeroFrames1+4
|
||||
|
||||
pha ; Space for result
|
||||
pea HERO_SIZE
|
||||
pea HERO_VBUFF_3
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
sta HeroFrames2+2
|
||||
sta HeroFrames2+6
|
||||
|
||||
pha ; Space for result
|
||||
pea HERO_SIZE
|
||||
pea HERO_VBUFF_4
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
sta HeroFrames2+0
|
||||
sta HeroFrames2+4
|
||||
FIN
|
||||
|
||||
pea HERO_SLOT_1 ; Put the player in slot 1
|
||||
lda SpriteFlags1
|
||||
pha
|
||||
lda HeroFrames1
|
||||
pha
|
||||
pei PlayerX
|
||||
pei PlayerY
|
||||
pea HERO_SLOT_1 ; Put the player in slot 1
|
||||
_GTEAddSprite
|
||||
|
||||
pea HERO_SLOT_1
|
||||
pea $0000
|
||||
pea HERO_VBUFF_1 ; and use this stamp
|
||||
_GTEUpdateSprite
|
||||
|
||||
pea HERO_FRAME_2
|
||||
pea HERO_SLOT_2
|
||||
lda SpriteFlags2
|
||||
pha
|
||||
lda HeroFrames2
|
||||
pha
|
||||
pei PlayerX
|
||||
lda PlayerY
|
||||
clc
|
||||
adc #16
|
||||
pha
|
||||
pea HERO_SLOT_2 ; Put the player in slot 1
|
||||
_GTEAddSprite
|
||||
|
||||
pea HERO_SLOT_2
|
||||
pea $0000
|
||||
pea HERO_VBUFF_3 ; and use this stamp
|
||||
_GTEUpdateSprite
|
||||
|
||||
EvtLoop
|
||||
pha
|
||||
_GTEReadControl
|
||||
|
@ -298,7 +342,9 @@ do_render
|
|||
pha
|
||||
_GTESetBG1Origin
|
||||
|
||||
pea #RENDER_BG1_HORZ_OFFSET
|
||||
; pea #RENDER_BG1_HORZ_OFFSET
|
||||
pea #RENDER_WITH_SHADOWING
|
||||
; pea #0
|
||||
_GTERender
|
||||
|
||||
; Update the performance counters
|
||||
|
@ -529,6 +575,10 @@ Fatal brk $00
|
|||
qtRec adrl $0000
|
||||
da $00
|
||||
|
||||
; Sprite VBUFF / Compile tokens
|
||||
SpriteFlags1 ds 2
|
||||
SpriteFlags2 ds 2
|
||||
|
||||
; Color palette
|
||||
MyDirectPage ds 2
|
||||
|
||||
|
|
|
@ -14,17 +14,17 @@
|
|||
},
|
||||
"scripts": {
|
||||
"test": "npm run build && npm run build:image && npm run gsport",
|
||||
"gsport": "%npm_package_config_gsport%",
|
||||
"debug": "%npm_package_config_crossrunner% GTEDemo4 -Source GTEDemo4_S02_MAINSEG_Output.txt -Debug -CompatibilityLayer",
|
||||
"gsport": "cross-var $npm_package_config_gsport",
|
||||
"debug": "cross-var $npm_package_config_crossrunner GTEDemo4 -Source GTEDemo4_S02_MAINSEG_Output.txt -Debug -CompatibilityLayer",
|
||||
"build:all": "npm run build:tiles && npm run build:map && npm run build:tool && npm run build:sys16 && npm run build:image",
|
||||
"build:map": "node %npm_package_config_tiled2iigs% ./assets/tiled/yoshi-1.json --force-masked --no-gen-tiles --output-dir ./gen",
|
||||
"build:tiles": "node %npm_package_config_png2iigs% ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --verbose --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:tiles:blocky": "node %npm_package_config_png2iigs% ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --verbose --force-word-alignment --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:sys16": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s",
|
||||
"build:map": "cross-var node $npm_package_config_tiled2iigs ./assets/tiled/yoshi-1.json --force-masked --no-gen-tiles --output-dir ./gen",
|
||||
"build:tiles": "cross-var node $npm_package_config_png2iigs ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --verbose --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:tiles:blocky": "cross-var node $npm_package_config_png2iigs ./assets/tilesets/smw-256x128-4bpp.png --max-tiles 360 --as-tile-data --verbose --force-word-alignment --transparent-color FF00FF --background-color 216058 > ./gen/App.TileSet.s",
|
||||
"build:sys16": "cross-var $npm_package_config_merlin32 -V $npm_package_config_macros App.s",
|
||||
"build": "npm run build:tool && npm run build:sys16",
|
||||
"build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../../src/Master.s",
|
||||
"build:image": "build-image.bat %npm_package_config_cadius%",
|
||||
"build:background": "node %npm_package_config_png2iigs% ./assets/tilesets/bg1.png ./gen/bg1.bin --force-color-match --palette FF00FF,C14F4A,020202,00E100,C89858,216058,DCE9EE,008000,F80080,F5D56C,20308F,A0CDCC,4080A0,70B0D0"
|
||||
"build:tool": "cross-var $npm_package_config_merlin32 -V $npm_package_config_macros ../../../src/Master.s",
|
||||
"build:image": "cross-var build-image.bat $npm_package_config_cadius",
|
||||
"build:background": "cross-var node $npm_package_config_png2iigs ./assets/tilesets/bg1.png ./gen/bg1.bin --force-color-match --palette FF00FF,C14F4A,020202,00E100,C89858,216058,DCE9EE,008000,F80080,F5D56C,20308F,A0CDCC,4080A0,70B0D0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -37,6 +37,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/lscharen/iigs-game-engine#readme",
|
||||
"devDependencies": {
|
||||
"cross-var": "^1.1.0",
|
||||
"pngjs": "^6.0.0",
|
||||
"string-builder": "^0.1.8",
|
||||
"watch": "latest",
|
||||
|
|
|
@ -301,9 +301,12 @@ DoLoadBG1
|
|||
ldx #BG1AltDataFile
|
||||
jsr LoadFile
|
||||
|
||||
lda altBG1Bank
|
||||
jsl SetBG1Bank
|
||||
|
||||
ldx BankLoad
|
||||
lda #0
|
||||
ldy BG1AltBank
|
||||
ldy BG1DataBank
|
||||
jsl CopyBinToBG1
|
||||
|
||||
rts
|
||||
|
|
|
@ -105,7 +105,7 @@ InitOverlay
|
|||
ldx #r_line+{CHAR_WIDTH*4}
|
||||
jsr _DrawChar
|
||||
|
||||
pea $0000
|
||||
pea $0000 ; logical lines for the overlay bar
|
||||
pea $0008
|
||||
pea #^StatusBar
|
||||
pea #StatusBar
|
||||
|
@ -174,6 +174,8 @@ oneSecondCounter ds 2
|
|||
|
||||
; Draw the overlay
|
||||
; A = address of the left edge of the screen
|
||||
; X = top line to start drawing the overlay (typically 0)
|
||||
; Y = bottom line to stop drawing the overlayer (typically the overlay height set during call to _SetOverlay)
|
||||
StatusBar phb ; Called via JSL
|
||||
phd ; save the direct page register
|
||||
|
||||
|
@ -273,6 +275,17 @@ r_ovrly
|
|||
--^
|
||||
jmp r_ovrly_rtn ; In R1W1, so can't use the stack
|
||||
|
||||
r_ovrly2
|
||||
]idx equ 0
|
||||
lup R_CHAR_COUNT
|
||||
lda r_line+]idx,x
|
||||
sta ]idx
|
||||
lda r_line+]idx+2,x
|
||||
sta ]idx+2
|
||||
]idx equ ]idx+4
|
||||
--^
|
||||
jmp r_ovrly_rtn ; In R1W1, so can't use the stack
|
||||
|
||||
l_ovrly
|
||||
]idx equ 0
|
||||
lup L_CHAR_COUNT
|
||||
|
@ -287,11 +300,23 @@ l_ovrly
|
|||
]idx equ ]idx+4
|
||||
--^
|
||||
jmp l_ovrly_rtn
|
||||
|
||||
|
||||
l_ovrly2
|
||||
]idx equ 0
|
||||
lup L_CHAR_COUNT
|
||||
lda l_line+]idx,x
|
||||
sta ]idx
|
||||
lda l_line+]idx+2,x
|
||||
sta ]idx+2
|
||||
]idx equ ]idx+4
|
||||
--^
|
||||
jmp l_ovrly_rtn
|
||||
|
||||
; Single TSB slam
|
||||
m_line
|
||||
]idx equ $9E
|
||||
lup 80 ; 80 words max for a full-width screen
|
||||
; sta ]idx
|
||||
tsb ]idx
|
||||
]idx equ ]idx-2
|
||||
--^
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
; IIgs Game Engine
|
||||
|
||||
TYP $B3 ; S16 file
|
||||
DSK GTETestApp
|
||||
DSK SuperMarioGS
|
||||
XPL
|
||||
|
||||
; Segment #1 -- Main execution block
|
||||
|
||||
ASM Main.s
|
||||
KND #$1100
|
||||
SNA MAIN
|
||||
|
||||
; Segment #2 -- ROM
|
||||
|
||||
ASM rom.s
|
||||
KND #$1100
|
||||
SNA SMBROM
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
SMBStart EXT ; Base address of the ROM. Should be XX/8000 in the bank the ROM is loaded into
|
|
@ -1,4 +1,51 @@
|
|||
REL
|
||||
DSK MAINSEG
|
||||
|
||||
rtl
|
||||
use Locator.Macs
|
||||
use Load.Macs
|
||||
use Mem.Macs
|
||||
use Misc.Macs
|
||||
use Util.Macs
|
||||
use EDS.GSOS.Macs
|
||||
use GTE.Macs
|
||||
use Externals.s
|
||||
|
||||
mx %00
|
||||
|
||||
; Direct page space
|
||||
MyUserId equ 0
|
||||
|
||||
phk
|
||||
plb
|
||||
sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program
|
||||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
pea $00A0 ; Load from System:Tools
|
||||
pea $0100 ; Tool160, version 1.0
|
||||
_LoadOneTool
|
||||
|
||||
clc ; Give GTE a page of direct page memory
|
||||
tdc
|
||||
adc #$0100
|
||||
pha
|
||||
pea $0000 ; Default fast mode
|
||||
lda MyUserId ; Pass the userId for memory allocation
|
||||
pha
|
||||
_GTEStartUp
|
||||
|
||||
; Initialize the graphics screen playfield (256x160). The NES is 240 lines high, so 160
|
||||
; is a reasonable compromise.
|
||||
|
||||
pea #160
|
||||
pea #200
|
||||
_GTESetScreenMode
|
||||
|
||||
; Convert the CHR ROM from the cart into GTE tiles
|
||||
|
||||
; jsr LoadTilesFromROM
|
||||
|
||||
|
||||
_GTEShutDown
|
||||
_QuitGS qtRec
|
||||
qtRec adrl $0000
|
||||
da $00
|
|
@ -1 +1 @@
|
|||
GTETestApp=Type(B3),AuxType(0000),VersionCreate(70),MinVersion(BE),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
||||
SuperMarioGS=Type(B3),AuxType(0000),VersionCreate(70),MinVersion(BE),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
echo off
|
||||
|
||||
REM Copy all of the assets into the ProDOS image for emulator testing
|
||||
REM
|
||||
REM Pass the path of the Cadius tool as the first argument (%1)
|
||||
|
||||
set CADIUS="%1"
|
||||
set IMAGE="..\\..\\emu\\Target.2mg"
|
||||
set FOLDER="/GTEDEV/SMB"
|
||||
|
||||
REM Cadius does not overwrite files, so clear the root folder first
|
||||
%CADIUS% DELETEFOLDER %IMAGE% %FOLDER%
|
||||
%CADIUS% CREATEFOLDER %IMAGE% %FOLDER%
|
||||
|
||||
REM Now copy files and folders as needed
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\SuperMarioGS
|
|
@ -0,0 +1,512 @@
|
|||
db $03,$0f,$1f,$1f,$1c,$24,$26,$66,$00,$00,$00,$00,$1f,$3f,$3f,$7f
|
||||
db $e0,$c0,$80,$fc,$80,$c0,$00,$20,$00,$20,$60,$00,$f0,$fc,$fe,$fe
|
||||
db $60,$70,$18,$07,$0f,$1f,$3f,$7f,$7f,$7f,$1f,$07,$00,$1e,$3f,$7f
|
||||
db $fc,$7c,$00,$00,$e0,$f0,$f8,$f8,$fc,$fc,$f8,$c0,$c2,$67,$2f,$37
|
||||
db $7f,$7f,$ff,$ff,$07,$07,$0f,$0f,$7f,$7e,$fc,$f0,$f8,$f8,$f0,$70
|
||||
db $fd,$fe,$b4,$f8,$f8,$f9,$fb,$ff,$37,$36,$5c,$00,$00,$01,$03,$1f
|
||||
db $1f,$3f,$ff,$ff,$fc,$70,$70,$38,$08,$24,$e3,$f0,$f8,$70,$70,$38
|
||||
db $ff,$ff,$ff,$1f,$00,$00,$00,$00,$1f,$1f,$1f,$1f,$00,$00,$00,$00
|
||||
db $00,$00,$01,$07,$0f,$0f,$0e,$12,$00,$00,$00,$00,$00,$00,$0f,$1f
|
||||
db $00,$00,$f0,$e0,$c0,$fe,$40,$60,$00,$00,$00,$10,$30,$00,$f8,$fe
|
||||
db $13,$33,$30,$18,$04,$0f,$1f,$1f,$1f,$3f,$3f,$1f,$07,$08,$17,$17
|
||||
db $00,$10,$7e,$3e,$00,$00,$c0,$e0,$ff,$ff,$fe,$fe,$fc,$e0,$40,$a0
|
||||
db $3f,$3f,$3f,$1f,$1f,$1f,$1f,$1f,$37,$27,$23,$03,$01,$00,$00,$00
|
||||
db $f0,$f0,$f0,$f8,$f8,$f8,$f8,$f8,$cc,$ff,$ff,$ff,$ff,$70,$00,$08
|
||||
db $ff,$ff,$ff,$fe,$f0,$c0,$80,$00,$f0,$f0,$f0,$f0,$f0,$c0,$80,$00
|
||||
db $fc,$fc,$f8,$78,$78,$78,$7e,$7e,$10,$60,$80,$00,$78,$78,$7e,$7e
|
||||
db $00,$03,$0f,$1f,$1f,$1c,$24,$26,$00,$00,$00,$00,$00,$1f,$3f,$3f
|
||||
db $00,$e0,$c0,$80,$fc,$80,$c0,$00,$00,$00,$20,$60,$00,$f0,$fc,$fe
|
||||
db $66,$60,$30,$18,$0f,$1f,$3f,$3f,$7f,$7f,$3f,$1f,$00,$16,$2f,$2f
|
||||
db $20,$fc,$7c,$00,$00,$e0,$e0,$f0,$fe,$fc,$fc,$f8,$c0,$60,$20,$30
|
||||
db $3f,$3f,$3f,$3f,$3f,$3f,$3f,$1f,$2f,$2f,$2f,$0f,$07,$03,$00,$00
|
||||
db $f0,$90,$00,$08,$0c,$1c,$fc,$f8,$10,$f0,$f0,$f0,$f0,$e0,$c0,$e0
|
||||
db $0f,$0f,$07,$07,$07,$0f,$0f,$03,$01,$03,$01,$04,$07,$0f,$0f,$03
|
||||
db $f8,$f0,$e0,$f0,$b0,$80,$e0,$e0,$f8,$f0,$e0,$70,$b0,$80,$e0,$e0
|
||||
db $03,$3f,$7f,$19,$09,$09,$28,$5c,$00,$30,$70,$7f,$ff,$ff,$f7,$f3
|
||||
db $f8,$e0,$e0,$fc,$26,$30,$80,$10,$00,$18,$10,$00,$f8,$f8,$fe,$ff
|
||||
db $3e,$1e,$3f,$38,$30,$30,$00,$3a,$e7,$0f,$0f,$1f,$1f,$1f,$0f,$07
|
||||
db $78,$1e,$80,$fe,$7e,$7e,$7f,$7f,$ff,$fe,$fc,$c6,$8e,$ee,$ff,$ff
|
||||
db $3c,$3f,$1f,$0f,$07,$3f,$21,$20,$03,$00,$00,$0e,$07,$3f,$3f,$3f
|
||||
db $ff,$ff,$ff,$fe,$fe,$fe,$fc,$70,$ff,$7f,$3f,$0e,$c0,$c0,$e0,$e0
|
||||
db $0f,$9f,$cf,$ff,$7f,$3f,$1e,$0e,$00,$80,$c8,$fe,$7f,$3f,$1e,$0e
|
||||
db $20,$c0,$80,$80,$00,$00,$00,$00,$e0,$00,$00,$00,$00,$00,$00,$00
|
||||
db $00,$00,$03,$0f,$1f,$1f,$1c,$24,$00,$00,$00,$00,$00,$00,$1f,$3f
|
||||
db $00,$04,$e6,$e0,$ff,$ff,$8f,$83,$0e,$1f,$1f,$1f,$1f,$03,$ff,$ff
|
||||
db $26,$26,$60,$78,$18,$0f,$7f,$ff,$3f,$3f,$7f,$7f,$1f,$00,$7e,$ff
|
||||
db $01,$21,$fe,$7a,$06,$fe,$fc,$fc,$ff,$ff,$fe,$fe,$fe,$de,$5c,$6c
|
||||
db $ff,$cf,$87,$07,$07,$0f,$1f,$1f,$ff,$ff,$fe,$fc,$f8,$b0,$60,$00
|
||||
db $f8,$f8,$f0,$b8,$f8,$f9,$fb,$ff,$28,$30,$18,$40,$00,$01,$03,$0f
|
||||
db $1f,$ff,$ff,$ff,$ff,$fe,$c0,$80,$10,$ec,$e3,$e0,$e0,$e0,$c0,$80
|
||||
db $ff,$ff,$ff,$3f,$00,$00,$00,$00,$0f,$0f,$0f,$0f,$00,$00,$00,$00
|
||||
db $13,$33,$30,$18,$04,$0f,$1f,$1f,$1f,$3f,$3f,$1f,$07,$09,$13,$17
|
||||
db $00,$10,$7e,$30,$e0,$f0,$f0,$e0,$ff,$ff,$fe,$ff,$fe,$fc,$f8,$e0
|
||||
db $1f,$1f,$0f,$0f,$0f,$1f,$1f,$1f,$17,$17,$03,$00,$00,$00,$00,$00
|
||||
db $f0,$f0,$f8,$f8,$b8,$f8,$f8,$f8,$d0,$90,$18,$08,$40,$00,$00,$00
|
||||
db $3f,$ff,$ff,$ff,$f6,$c6,$84,$00,$30,$f0,$f0,$f1,$f6,$c6,$84,$00
|
||||
db $f0,$e0,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $1f,$1f,$3f,$3f,$1f,$0f,$0f,$1f,$1f,$1f,$3f,$3e,$7c,$78,$f0,$e0
|
||||
db $f0,$f0,$f8,$f8,$b8,$f8,$f8,$f0,$b0,$90,$18,$08,$40,$00,$00,$00
|
||||
db $e0,$f0,$f0,$f0,$f0,$f0,$f8,$f0,$c0,$e0,$fc,$fe,$ff,$7f,$03,$00
|
||||
db $1f,$1f,$1f,$3f,$3e,$3c,$38,$18,$00,$00,$10,$38,$3e,$3c,$38,$18
|
||||
db $00,$03,$07,$07,$0a,$0b,$0c,$00,$00,$00,$00,$07,$0f,$0f,$0f,$03
|
||||
db $00,$e0,$fc,$20,$20,$10,$3c,$00,$00,$00,$00,$f0,$fc,$fe,$fc,$f8
|
||||
db $07,$07,$07,$1f,$1f,$3e,$21,$01,$07,$0f,$1b,$18,$10,$30,$21,$01
|
||||
db $e0,$e0,$e0,$f0,$f0,$e0,$c0,$e0,$a8,$fc,$f8,$00,$00,$00,$c0,$e0
|
||||
db $07,$0f,$0e,$14,$16,$18,$00,$3f,$00,$00,$0f,$1f,$1f,$1f,$07,$3c
|
||||
db $c0,$f8,$40,$40,$20,$78,$00,$c0,$00,$00,$e0,$f8,$fc,$f8,$f0,$c0
|
||||
db $3f,$0e,$0f,$1f,$3f,$7c,$70,$38,$fc,$ed,$c0,$00,$00,$60,$70,$38
|
||||
db $f0,$f8,$e4,$fc,$fc,$7c,$00,$00,$7e,$1e,$04,$0c,$0c,$0c,$00,$00
|
||||
db $07,$0f,$0e,$14,$16,$18,$00,$0f,$00,$00,$0f,$1f,$1f,$1f,$07,$0d
|
||||
db $1f,$1f,$1f,$1c,$0c,$07,$07,$07,$1e,$1c,$1e,$0f,$07,$00,$07,$07
|
||||
db $e0,$60,$f0,$70,$e0,$e0,$f0,$80,$60,$90,$00,$80,$00,$e0,$f0,$80
|
||||
db $07,$1f,$3f,$12,$13,$08,$1f,$31,$00,$10,$3f,$7f,$7f,$3f,$03,$0f
|
||||
db $c0,$f0,$40,$00,$30,$18,$c0,$f8,$00,$00,$e0,$f8,$fc,$f8,$b0,$38
|
||||
db $31,$39,$1f,$1f,$0f,$5f,$7e,$3c,$1f,$07,$00,$0e,$0f,$53,$7c,$3c
|
||||
db $f8,$f8,$f0,$e0,$e0,$c0,$00,$00,$f8,$f8,$f0,$00,$00,$80,$00,$00
|
||||
db $00,$e0,$fc,$27,$27,$11,$3e,$04,$07,$07,$03,$f7,$ff,$ff,$fe,$fc
|
||||
db $3f,$7f,$3f,$0f,$1f,$3f,$7f,$4f,$3e,$7f,$ff,$e2,$50,$38,$70,$40
|
||||
db $f8,$f9,$f9,$b7,$ff,$ff,$e0,$00,$e8,$71,$01,$4b,$03,$03,$00,$00
|
||||
db $07,$07,$0f,$3f,$3f,$3f,$26,$04,$05,$03,$01,$30,$30,$30,$26,$04
|
||||
db $f0,$f0,$f0,$e0,$c0,$00,$00,$00,$fe,$fc,$e0,$00,$00,$00,$00,$00
|
||||
db $07,$07,$0f,$1f,$3f,$0f,$1c,$18,$05,$03,$01,$10,$30,$0c,$1c,$18
|
||||
db $e0,$e0,$e0,$e0,$c0,$80,$00,$00,$c0,$e0,$f0,$78,$18,$08,$00,$00
|
||||
db $07,$0f,$1f,$0f,$3f,$0f,$1c,$18,$07,$0f,$3e,$7c,$30,$0c,$1c,$18
|
||||
db $e0,$e0,$e0,$40,$c0,$80,$00,$00,$60,$60,$60,$80,$00,$00,$00,$00
|
||||
db $7f,$ff,$ff,$fb,$0f,$0f,$0f,$1f,$73,$f3,$f0,$f4,$f0,$f0,$70,$60
|
||||
db $3f,$7e,$7c,$7c,$3c,$3c,$fc,$fc,$00,$00,$00,$00,$3c,$3c,$fc,$fc
|
||||
db $60,$70,$18,$08,$0f,$1f,$3f,$7f,$7f,$7f,$1f,$07,$0b,$1b,$3b,$7b
|
||||
db $fc,$7c,$00,$20,$f0,$f8,$fc,$fe,$fc,$fc,$f8,$e0,$d0,$d8,$dc,$de
|
||||
db $0b,$0f,$1f,$1e,$3c,$3c,$3c,$7c,$c4,$e0,$e0,$40,$00,$3c,$3c,$7c
|
||||
db $1f,$3f,$0d,$07,$0f,$0e,$1c,$3c,$1d,$3c,$3a,$38,$30,$00,$1c,$3c
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$22,$55,$55,$55,$55,$55,$77,$22
|
||||
db $00,$07,$1f,$ff,$07,$1f,$0f,$06,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $3f,$ff,$ff,$ff,$ff,$ff,$fb,$76,$00,$00,$cf,$07,$7f,$00,$00,$00
|
||||
db $20,$f8,$ff,$c3,$fd,$fe,$f0,$40,$00,$00,$3c,$fc,$fe,$e0,$00,$00
|
||||
db $40,$e0,$40,$40,$41,$41,$4f,$47,$40,$e0,$40,$3f,$3e,$3e,$30,$38
|
||||
db $00,$00,$00,$00,$00,$00,$e0,$c0,$00,$00,$00,$f8,$f8,$f8,$18,$38
|
||||
db $43,$46,$44,$40,$40,$40,$40,$40,$3c,$39,$3b,$3f,$00,$00,$00,$00
|
||||
db $80,$c0,$40,$00,$00,$00,$00,$00,$78,$38,$b8,$f8,$00,$00,$00,$00
|
||||
db $31,$30,$38,$7c,$7f,$ff,$ff,$fb,$3f,$3f,$0f,$77,$77,$f7,$f7,$f7
|
||||
db $10,$7e,$3e,$00,$1e,$fe,$ff,$ff,$ff,$fe,$fe,$fe,$fa,$fa,$f3,$e7
|
||||
db $ff,$ff,$e3,$c3,$87,$48,$3c,$fc,$f0,$f8,$fc,$7c,$78,$38,$3c,$fc
|
||||
db $00,$ff,$c3,$83,$83,$ff,$ff,$ff,$ff,$00,$c3,$81,$81,$c3,$ff,$00
|
||||
db $1f,$1f,$0f,$07,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $f0,$fb,$ff,$ff,$fe,$3e,$0c,$04,$00,$0b,$1f,$1f,$1e,$3e,$0c,$04
|
||||
db $1f,$1f,$0f,$0f,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fb,$ff,$ff,$ff,$ff,$00,$00,$00,$03,$0f,$0f,$0f,$0f,$00,$00,$00
|
||||
db $00,$18,$3c,$7e,$6e,$df,$df,$df,$00,$18,$3c,$7e,$76,$fb,$fb,$fb
|
||||
db $00,$18,$18,$3c,$3c,$3c,$3c,$1c,$00,$10,$10,$20,$20,$20,$20,$20
|
||||
db $00,$08,$08,$08,$08,$08,$08,$00,$00,$08,$08,$08,$08,$08,$08,$08
|
||||
db $00,$08,$08,$04,$04,$04,$04,$04,$00,$10,$10,$38,$38,$38,$38,$38
|
||||
db $3c,$7e,$77,$fb,$9f,$5f,$8e,$20,$00,$18,$3c,$0e,$0e,$04,$00,$00
|
||||
db $5c,$2e,$8f,$3f,$7b,$77,$7e,$3c,$00,$00,$04,$06,$1e,$3c,$18,$00
|
||||
db $13,$4f,$3f,$bf,$3f,$7a,$f8,$f8,$00,$00,$01,$0a,$17,$0f,$2f,$1f
|
||||
db $00,$08,$05,$0f,$2f,$1d,$1c,$3c,$00,$00,$00,$00,$05,$07,$0f,$07
|
||||
db $00,$00,$00,$00,$02,$0b,$07,$0f,$00,$00,$00,$00,$00,$00,$01,$03
|
||||
db $00,$00,$00,$00,$00,$08,$04,$04,$00,$60,$f0,$f8,$7c,$3e,$7e,$7f
|
||||
db $02,$02,$02,$05,$71,$7f,$7f,$7f,$3f,$5f,$7f,$3e,$0e,$0a,$51,$20
|
||||
db $00,$00,$00,$00,$00,$00,$00,$04,$00,$00,$00,$00,$00,$00,$0e,$1f
|
||||
db $02,$02,$00,$01,$13,$3f,$7f,$7f,$3f,$7f,$7f,$fe,$ec,$ca,$51,$20
|
||||
db $00,$40,$60,$70,$73,$27,$0f,$1f,$00,$40,$63,$77,$7c,$38,$f8,$e4
|
||||
db $00,$00,$00,$00,$03,$07,$0f,$1f,$00,$00,$03,$07,$0c,$18,$f8,$e4
|
||||
db $7f,$7f,$3f,$3f,$1f,$1f,$0f,$07,$03,$44,$28,$10,$08,$04,$03,$04
|
||||
db $03,$07,$0f,$1f,$3f,$77,$77,$f5,$03,$07,$0f,$1f,$27,$7b,$78,$fb
|
||||
db $c0,$e0,$f0,$f8,$fc,$ee,$ee,$af,$c0,$e0,$f0,$f8,$e4,$de,$1e,$df
|
||||
db $f1,$ff,$78,$00,$00,$18,$1c,$0e,$ff,$ff,$7f,$0f,$0f,$07,$03,$00
|
||||
db $8f,$ff,$1e,$00,$0c,$3e,$7e,$7c,$ff,$ff,$fe,$f0,$f0,$c0,$80,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$24,$24,$18,$00,$00
|
||||
db $00,$02,$41,$41,$61,$33,$06,$3c,$3c,$7e,$ff,$ff,$ff,$ff,$7e,$3c
|
||||
db $03,$07,$0f,$1f,$3f,$7f,$7f,$ff,$03,$07,$0f,$1f,$3f,$63,$41,$c1
|
||||
db $c0,$e0,$f0,$f8,$fc,$fe,$fe,$ff,$c0,$80,$00,$00,$8c,$fe,$fe,$f3
|
||||
db $ff,$ff,$ff,$78,$00,$00,$00,$00,$c1,$e3,$ff,$47,$0f,$0f,$0f,$07
|
||||
db $ff,$ff,$ff,$1e,$00,$20,$20,$40,$f1,$f9,$ff,$e2,$f0,$f0,$f0,$e0
|
||||
db $16,$1f,$3f,$7f,$3d,$1d,$3f,$1f,$16,$1f,$00,$00,$05,$0d,$3f,$1f
|
||||
db $80,$80,$c0,$e0,$f0,$f0,$f0,$f8,$80,$80,$00,$00,$00,$a0,$a0,$e0
|
||||
db $3c,$fa,$b1,$72,$f2,$db,$df,$5f,$00,$04,$4e,$8c,$0c,$7f,$ff,$ff
|
||||
db $00,$00,$00,$01,$01,$01,$06,$1e,$00,$00,$00,$00,$00,$00,$01,$01
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$ff,$7f,$3f,$1f,$0f,$07,$03,$01
|
||||
db $00,$7c,$d6,$92,$ba,$ee,$fe,$38,$ff,$83,$29,$6d,$45,$11,$01,$c7
|
||||
db $00,$15,$3f,$62,$5f,$ff,$9f,$7d,$08,$08,$02,$1f,$22,$02,$02,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$08,$08,$08,$08,$08,$08,$08,$08
|
||||
db $2f,$1e,$2f,$2f,$2f,$15,$0d,$0e,$10,$1e,$10,$50,$10,$08,$00,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$fe,$00,$00,$00,$00
|
||||
db $1c,$3e,$7f,$ff,$ff,$fe,$7c,$38,$1c,$2a,$77,$ee,$dd,$aa,$74,$28
|
||||
db $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$fe,$00,$ef,$ef,$ef,$00
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$fe,$fe,$00,$ef,$ef,$ef,$00
|
||||
db $7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$7f,$5f,$7f,$7f,$7f,$7f,$7f
|
||||
db $68,$4e,$e0,$e0,$e0,$f0,$f8,$fc,$b8,$9e,$80,$c0,$e0,$f0,$f8,$7c
|
||||
db $3f,$5c,$39,$3b,$bb,$f9,$fc,$fe,$00,$23,$57,$4f,$57,$27,$c3,$21
|
||||
db $c0,$f0,$f0,$f0,$f0,$e0,$c0,$00,$00,$30,$70,$70,$f0,$e0,$c0,$00
|
||||
db $fe,$fc,$61,$0f,$ff,$fe,$f0,$e0,$13,$0f,$1e,$f0,$fc,$f8,$f0,$e0
|
||||
db $6e,$40,$e0,$e0,$e0,$e0,$e0,$c0,$be,$90,$80,$c0,$c0,$80,$00,$00
|
||||
db $01,$01,$03,$03,$07,$7f,$7f,$3f,$01,$01,$03,$03,$07,$7f,$7d,$3d
|
||||
db $06,$07,$3f,$3c,$19,$7b,$7f,$3f,$06,$04,$30,$23,$06,$64,$60,$00
|
||||
db $3f,$7f,$7f,$1f,$3f,$3f,$07,$06,$00,$60,$60,$00,$20,$30,$04,$06
|
||||
db $03,$07,$0f,$0f,$0f,$0f,$07,$03,$00,$01,$01,$00,$00,$00,$00,$00
|
||||
db $f8,$f8,$f8,$a0,$e1,$ff,$ff,$ff,$fe,$ff,$ff,$40,$01,$03,$03,$03
|
||||
db $0f,$0f,$0f,$1f,$1f,$1f,$0f,$07,$01,$01,$00,$00,$00,$00,$00,$00
|
||||
db $e0,$f8,$f8,$f8,$ff,$fe,$f0,$c0,$e0,$fe,$ff,$7f,$03,$02,$00,$00
|
||||
db $01,$0f,$0f,$1f,$39,$33,$37,$7f,$01,$0d,$08,$00,$36,$2c,$08,$60
|
||||
db $7f,$3f,$3f,$3f,$1f,$0f,$0f,$01,$60,$00,$20,$30,$00,$08,$0d,$01
|
||||
db $00,$00,$03,$03,$47,$67,$77,$77,$01,$01,$03,$43,$67,$77,$7b,$78
|
||||
db $00,$00,$00,$00,$88,$98,$f8,$f0,$00,$00,$80,$84,$cc,$dc,$bc,$3c
|
||||
db $7e,$7f,$ff,$1f,$07,$30,$1c,$0c,$33,$07,$07,$e3,$38,$3f,$1c,$0c
|
||||
db $7e,$38,$f6,$ed,$df,$38,$70,$60,$98,$c7,$c8,$92,$30,$f8,$70,$60
|
||||
db $00,$00,$00,$03,$03,$47,$67,$77,$00,$01,$01,$03,$43,$67,$77,$7b
|
||||
db $00,$00,$00,$00,$00,$88,$98,$f8,$00,$00,$00,$80,$84,$cc,$dc,$bc
|
||||
db $77,$7e,$7f,$ff,$1f,$07,$70,$f0,$78,$33,$07,$07,$e3,$38,$7f,$f0
|
||||
db $f0,$7e,$38,$f6,$ed,$df,$38,$3c,$3c,$98,$c7,$c8,$92,$30,$f8,$3c
|
||||
db $03,$07,$0a,$1a,$1c,$1e,$0b,$08,$00,$10,$7f,$7f,$7f,$1f,$0f,$0f
|
||||
db $1c,$3f,$3f,$3d,$3f,$1f,$00,$00,$03,$33,$39,$3a,$38,$18,$00,$00
|
||||
db $00,$00,$04,$4c,$4e,$4e,$46,$6f,$10,$38,$3c,$74,$76,$76,$7e,$7d
|
||||
db $00,$1f,$3f,$3f,$4f,$5f,$7f,$7f,$00,$00,$11,$0a,$34,$2a,$51,$20
|
||||
db $7f,$67,$a3,$b0,$d8,$de,$dc,$c8,$7f,$67,$63,$70,$38,$3e,$7c,$b8
|
||||
db $7f,$7f,$7f,$1f,$47,$70,$70,$39,$51,$0a,$04,$ea,$79,$7f,$70,$39
|
||||
db $e8,$e8,$e0,$c0,$10,$70,$e0,$c0,$58,$38,$10,$30,$f0,$f0,$e0,$c0
|
||||
db $00,$00,$00,$20,$66,$66,$66,$62,$00,$08,$1c,$3c,$7a,$7a,$7a,$7e
|
||||
db $00,$00,$1f,$3f,$7f,$4f,$5f,$7f,$00,$00,$00,$11,$0a,$34,$2a,$51
|
||||
db $77,$7f,$3f,$b7,$b3,$db,$da,$d8,$7f,$7d,$3f,$37,$33,$3b,$3a,$78
|
||||
db $7f,$7f,$7f,$7f,$1f,$07,$70,$f0,$20,$51,$0a,$04,$ea,$39,$7f,$f0
|
||||
db $cc,$e8,$e8,$e0,$c0,$18,$7c,$3e,$bc,$58,$38,$10,$30,$f8,$fc,$3e
|
||||
db $03,$0f,$1f,$3f,$3b,$3f,$7f,$7f,$00,$00,$00,$06,$0e,$0c,$00,$00
|
||||
db $80,$f0,$f8,$fc,$fe,$fe,$ff,$fe,$00,$00,$00,$00,$00,$00,$0f,$18
|
||||
db $7f,$7f,$7f,$7f,$ff,$0f,$03,$00,$00,$00,$00,$00,$f8,$3e,$3b,$18
|
||||
db $fe,$fb,$ff,$ff,$f6,$e0,$c0,$00,$10,$14,$10,$10,$38,$78,$f8,$30
|
||||
db $00,$03,$0f,$1f,$3f,$3b,$3f,$7f,$00,$00,$00,$00,$06,$0e,$0c,$00
|
||||
db $00,$c0,$f0,$f8,$fc,$fe,$fe,$ff,$00,$00,$00,$00,$00,$00,$00,$0f
|
||||
db $7f,$7f,$7f,$7f,$7f,$ff,$0f,$03,$00,$00,$00,$00,$00,$f8,$7e,$f3
|
||||
db $fe,$fe,$fb,$ff,$ff,$f6,$e0,$c0,$18,$10,$14,$10,$10,$38,$7c,$de
|
||||
db $00,$01,$01,$01,$01,$00,$00,$08,$00,$0d,$1e,$1e,$1e,$1f,$0f,$07
|
||||
db $78,$f0,$f8,$e4,$c0,$ca,$ca,$c0,$78,$f0,$00,$1a,$3f,$35,$35,$3f
|
||||
db $0f,$1f,$9f,$ff,$ff,$7f,$74,$20,$00,$00,$80,$e0,$e0,$70,$73,$21
|
||||
db $e4,$ff,$fe,$fc,$9c,$1e,$00,$00,$1a,$07,$0c,$18,$78,$fe,$fc,$f0
|
||||
db $00,$01,$03,$03,$07,$03,$01,$00,$00,$01,$02,$00,$38,$7c,$7e,$3f
|
||||
db $00,$5f,$7f,$7f,$3f,$3f,$14,$00,$3f,$40,$60,$60,$20,$30,$13,$01
|
||||
db $c0,$e0,$f0,$30,$38,$3c,$3c,$fc,$c0,$e0,$30,$d0,$d0,$d0,$d0,$00
|
||||
db $07,$0f,$1f,$22,$20,$25,$25,$1f,$07,$0f,$02,$1d,$1f,$1a,$1a,$02
|
||||
db $fe,$fe,$7e,$3a,$02,$01,$41,$41,$38,$7c,$fc,$fc,$fc,$fe,$be,$be
|
||||
db $1f,$3f,$7e,$5c,$40,$80,$82,$82,$1c,$3e,$3f,$3f,$3f,$7f,$7d,$7d
|
||||
db $82,$80,$a0,$44,$43,$40,$21,$1e,$7d,$7f,$5f,$3b,$3c,$3f,$1e,$00
|
||||
db $1c,$3f,$3e,$3c,$40,$80,$82,$82,$1c,$3e,$3f,$1f,$3f,$7f,$7d,$7d
|
||||
db $00,$00,$80,$80,$92,$9d,$c7,$ef,$00,$00,$00,$60,$62,$65,$3f,$1f
|
||||
db $00,$23,$33,$3f,$3f,$7f,$7f,$7f,$70,$3c,$3c,$18,$00,$00,$02,$07
|
||||
db $fe,$f8,$a0,$00,$00,$00,$80,$80,$cf,$7a,$5a,$10,$00,$00,$c0,$80
|
||||
db $7e,$7f,$7d,$3f,$1e,$8f,$8f,$19,$85,$84,$86,$c6,$e7,$73,$73,$e1
|
||||
db $e0,$0e,$73,$f3,$f9,$f9,$f8,$70,$80,$4e,$77,$f3,$fb,$f9,$fa,$78
|
||||
db $0e,$66,$e2,$f6,$ff,$ff,$1f,$98,$11,$39,$7d,$39,$00,$00,$e0,$e7
|
||||
db $00,$00,$00,$04,$0f,$0f,$1f,$07,$00,$00,$07,$07,$16,$10,$00,$38
|
||||
db $f3,$e7,$ee,$ec,$cd,$cf,$cf,$df,$cf,$1f,$17,$10,$33,$30,$30,$20
|
||||
db $27,$3f,$3f,$78,$3c,$1f,$1f,$73,$38,$30,$40,$c7,$07,$66,$e0,$6c
|
||||
db $9f,$3e,$7c,$fc,$f8,$f8,$c0,$40,$60,$c0,$80,$04,$9e,$ff,$f0,$f8
|
||||
db $7f,$7e,$78,$01,$07,$1f,$3c,$7c,$24,$01,$07,$fe,$ff,$7f,$3f,$7f
|
||||
db $fc,$f8,$a0,$fe,$fc,$f0,$80,$00,$cf,$7a,$0a,$fe,$fc,$00,$00,$00
|
||||
db $7e,$7f,$7f,$3f,$1f,$8f,$8f,$18,$85,$86,$83,$c3,$e1,$70,$70,$e0
|
||||
db $9f,$3e,$7c,$f8,$f8,$3c,$18,$f8,$60,$c0,$80,$00,$98,$fc,$fe,$ff
|
||||
db $7f,$7f,$78,$01,$07,$13,$f1,$03,$24,$00,$07,$fe,$ff,$7f,$ff,$03
|
||||
db $00,$00,$1c,$1d,$1b,$c3,$e3,$e1,$03,$0f,$23,$62,$64,$3c,$1c,$1e
|
||||
db $e0,$cd,$1d,$4f,$ee,$ff,$3f,$3f,$1f,$3d,$6d,$4f,$ee,$f3,$20,$03
|
||||
db $3f,$3f,$00,$00,$70,$b8,$fc,$fc,$07,$07,$1f,$3f,$0f,$47,$03,$00
|
||||
db $07,$0f,$1f,$3f,$3e,$7c,$78,$78,$00,$00,$03,$07,$0f,$0f,$1f,$1f
|
||||
db $3f,$5c,$39,$3b,$bf,$ff,$fe,$fe,$00,$23,$57,$4f,$57,$2f,$df,$21
|
||||
db $c0,$c0,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$80,$80,$00,$00
|
||||
db $fe,$fc,$61,$0f,$7f,$3f,$1f,$1e,$23,$0f,$1e,$f0,$1c,$3f,$1f,$1e
|
||||
db $f0,$78,$e4,$c8,$cc,$be,$be,$3e,$00,$80,$18,$30,$34,$fe,$fe,$fe
|
||||
db $00,$01,$00,$07,$07,$07,$07,$1f,$00,$00,$01,$04,$06,$06,$07,$07
|
||||
db $00,$00,$0f,$3f,$3f,$0f,$00,$00,$0f,$3f,$7f,$f8,$f8,$7f,$3f,$0f
|
||||
db $78,$7c,$7e,$7f,$3f,$3f,$1b,$09,$1f,$1f,$1f,$0b,$01,$01,$00,$00
|
||||
db $0c,$00,$00,$00,$07,$7f,$7c,$00,$03,$1f,$3f,$3f,$78,$00,$03,$ff
|
||||
db $01,$e1,$71,$79,$3d,$3d,$1f,$03,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $3f,$3f,$1f,$1b,$36,$30,$7f,$3f,$23,$27,$1f,$07,$0f,$1f,$7f,$3f
|
||||
db $f8,$f8,$f8,$b8,$18,$d8,$d8,$b8,$e0,$80,$80,$40,$e0,$e0,$e0,$c0
|
||||
db $01,$02,$04,$04,$08,$08,$10,$10,$03,$07,$0f,$1f,$3f,$7f,$ff,$1f
|
||||
db $00,$0f,$13,$0d,$0d,$13,$0c,$20,$1f,$10,$0c,$12,$12,$2c,$3f,$3f
|
||||
db $00,$24,$00,$24,$00,$04,$00,$00,$37,$36,$36,$36,$16,$16,$12,$02
|
||||
db $0f,$41,$00,$88,$00,$44,$00,$00,$10,$7e,$ff,$ff,$f6,$76,$3a,$1a
|
||||
db $38,$7c,$fe,$fe,$3b,$03,$03,$03,$00,$00,$38,$04,$00,$00,$00,$00
|
||||
db $03,$33,$7b,$7f,$ff,$fb,$03,$03,$00,$00,$00,$38,$40,$00,$00,$00
|
||||
db $dc,$c0,$e0,$e0,$e0,$e0,$e0,$c0,$fc,$a0,$80,$80,$00,$00,$00,$00
|
||||
db $3f,$5f,$3f,$3f,$bb,$f8,$fe,$fe,$07,$27,$57,$4f,$57,$27,$c1,$21
|
||||
db $1f,$0f,$0f,$1f,$1f,$1e,$38,$30,$1d,$0f,$0f,$1f,$1f,$1e,$38,$30
|
||||
db $00,$20,$60,$60,$70,$f0,$f8,$f8,$00,$00,$38,$10,$4c,$18,$86,$24
|
||||
db $f8,$fc,$fc,$7e,$7e,$3e,$1f,$07,$00,$42,$0a,$40,$10,$02,$08,$02
|
||||
db $00,$c0,$70,$b8,$f4,$f2,$f5,$7b,$00,$00,$80,$40,$08,$0c,$0a,$84
|
||||
db $00,$df,$10,$ff,$df,$ff,$ff,$f9,$00,$00,$cf,$20,$20,$20,$26,$2e
|
||||
db $1f,$1f,$3e,$fc,$f8,$f0,$c0,$00,$e0,$e0,$c0,$00,$00,$00,$00,$00
|
||||
db $f8,$fc,$fe,$ff,$ff,$df,$df,$00,$2f,$23,$21,$20,$20,$00,$00,$00
|
||||
db $c1,$f1,$79,$7d,$3d,$3f,$1f,$03,$c1,$b1,$59,$6d,$35,$3b,$1f,$03
|
||||
db $02,$06,$0e,$0e,$1e,$1e,$3e,$3e,$00,$02,$00,$08,$02,$00,$28,$00
|
||||
db $3e,$3e,$3e,$3e,$1e,$1e,$0e,$02,$04,$10,$02,$10,$04,$00,$0a,$00
|
||||
db $c1,$f1,$79,$7d,$3d,$3f,$1f,$03,$c1,$b1,$59,$6d,$35,$3b,$1f,$03
|
||||
db $7c,$00,$00,$ff,$c3,$7f,$1f,$03,$00,$0f,$1f,$ff,$fc,$63,$1f,$03
|
||||
db $ff,$ff,$7c,$00,$00,$7c,$ff,$ff,$00,$00,$fe,$c6,$c6,$fe,$00,$00
|
||||
db $ff,$ff,$00,$04,$0c,$18,$30,$00,$00,$00,$06,$06,$0c,$18,$70,$60
|
||||
db $ff,$ff,$00,$04,$04,$04,$08,$08,$00,$00,$06,$06,$04,$04,$08,$08
|
||||
db $08,$10,$10,$00,$00,$10,$10,$08,$08,$10,$30,$30,$30,$30,$10,$08
|
||||
db $7f,$3f,$3f,$3e,$1f,$0f,$03,$00,$00,$00,$01,$03,$01,$00,$00,$00
|
||||
db $03,$0f,$ff,$7f,$7f,$7f,$7f,$7f,$03,$0e,$f8,$00,$00,$00,$00,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$22,$65,$25,$25,$25,$25,$77,$72
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$62,$95,$15,$25,$45,$85,$f7,$f2
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$a2,$a5,$a5,$a5,$f5,$f5,$27,$22
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$f2,$85,$85,$e5,$15,$15,$f7,$e2
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$62,$95,$55,$65,$b5,$95,$97,$62
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$20,$50,$50,$50,$50,$50,$70,$20
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$66,$e6,$66,$66,$66,$67,$f3,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$5e,$59,$59,$59,$5e,$d8,$98,$00
|
||||
db $00,$00,$00,$00,$00,$7c,$38,$00,$00,$00,$00,$00,$00,$04,$08,$00
|
||||
db $38,$4c,$c6,$c6,$c6,$64,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $18,$38,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7c,$c6,$0e,$3c,$78,$e0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7e,$0c,$18,$3c,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $1c,$3c,$6c,$cc,$fe,$0c,$0c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fc,$c0,$fc,$06,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $3c,$60,$c0,$fc,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fe,$c6,$0c,$18,$30,$30,$30,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7c,$c6,$c6,$7c,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7c,$c6,$c6,$7e,$06,$0c,$78,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $38,$6c,$c6,$c6,$fe,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fc,$c6,$c6,$fc,$c6,$c6,$fc,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $3c,$66,$c0,$c0,$c0,$66,$3c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $f8,$cc,$c6,$c6,$c6,$cc,$f8,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fe,$c0,$c0,$fc,$c0,$c0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fe,$c0,$c0,$fc,$c0,$c0,$c0,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $3e,$60,$c0,$ce,$c6,$66,$3e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$c6,$fe,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7e,$18,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $1e,$06,$06,$06,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$cc,$d8,$f0,$f8,$dc,$ce,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $60,$60,$60,$60,$60,$60,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$ee,$fe,$fe,$d6,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$e6,$f6,$fe,$de,$ce,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7c,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fc,$c6,$c6,$c6,$fc,$c0,$c0,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7c,$c6,$c6,$c6,$de,$cc,$7a,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fc,$c6,$c6,$ce,$f8,$dc,$ce,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $78,$cc,$c0,$7c,$06,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7e,$18,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$c6,$ee,$7c,$38,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$d6,$fe,$fe,$ee,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$ee,$7c,$38,$7c,$ee,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $66,$66,$66,$3c,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fe,$0e,$1c,$38,$70,$e0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $00,$00,$00,$7e,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $00,$00,$44,$28,$10,$28,$44,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
|
||||
db $18,$3c,$3c,$3c,$18,$18,$00,$18,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $ff,$7f,$7f,$7f,$7f,$ff,$e3,$c1,$ff,$80,$80,$80,$80,$00,$1c,$3e
|
||||
db $80,$80,$80,$c1,$e3,$ff,$ff,$ff,$7f,$7f,$7f,$3e,$1c,$00,$00,$ff
|
||||
db $38,$7c,$7c,$7c,$7c,$7c,$38,$00,$08,$04,$04,$04,$04,$04,$08,$00
|
||||
db $03,$06,$0c,$0c,$08,$08,$04,$03,$03,$05,$0b,$0b,$0f,$0f,$07,$03
|
||||
db $01,$02,$04,$08,$10,$20,$40,$80,$01,$03,$07,$0f,$1f,$3f,$7f,$ff
|
||||
db $00,$00,$00,$00,$00,$07,$38,$c0,$00,$00,$00,$00,$00,$07,$3f,$ff
|
||||
db $00,$00,$00,$00,$00,$e0,$1c,$03,$00,$00,$00,$00,$00,$e0,$fc,$ff
|
||||
db $80,$40,$20,$10,$08,$04,$02,$01,$80,$c0,$e0,$f0,$f8,$fc,$fe,$ff
|
||||
db $04,$0e,$0e,$0e,$6e,$64,$60,$60,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $07,$0f,$1f,$1f,$7f,$ff,$ff,$7f,$07,$08,$10,$00,$60,$80,$80,$40
|
||||
db $03,$07,$1f,$3f,$3f,$3f,$79,$f7,$03,$04,$18,$20,$20,$20,$46,$88
|
||||
db $c0,$e0,$f0,$f4,$fe,$bf,$df,$ff,$c0,$20,$10,$14,$0a,$41,$21,$01
|
||||
db $90,$b8,$f8,$fa,$ff,$ff,$ff,$fe,$90,$a8,$48,$0a,$05,$01,$01,$02
|
||||
db $3b,$1d,$0e,$0f,$07,$00,$00,$00,$24,$12,$09,$08,$07,$00,$00,$00
|
||||
db $ff,$bf,$1c,$c0,$f3,$ff,$7e,$1c,$00,$40,$e3,$3f,$0c,$81,$62,$1c
|
||||
db $bf,$7f,$3d,$83,$c7,$ff,$ff,$3c,$40,$80,$c2,$7c,$38,$00,$c3,$3c
|
||||
db $fc,$fe,$ff,$fe,$fe,$f8,$60,$00,$04,$02,$01,$00,$06,$98,$60,$00
|
||||
db $c0,$20,$10,$10,$10,$10,$20,$c0,$c0,$e0,$f0,$f0,$f0,$f0,$e0,$c0
|
||||
db $00,$00,$00,$00,$3f,$7f,$e0,$c0,$00,$00,$00,$00,$00,$00,$1c,$3e
|
||||
db $88,$9c,$88,$80,$80,$80,$80,$80,$7f,$7f,$7f,$3e,$1c,$00,$00,$00
|
||||
db $fe,$fe,$fe,$fe,$fe,$fe,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $08,$14,$24,$c4,$03,$40,$a1,$26,$00,$08,$18,$38,$fc,$bf,$5e,$d9
|
||||
db $ff,$ff,$ff,$ff,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$01,$01,$01,$01,$01,$01,$01
|
||||
db $7f,$80,$80,$98,$9c,$8c,$80,$80,$00,$7f,$7f,$67,$67,$7f,$7f,$7f
|
||||
db $ff,$01,$01,$ff,$10,$10,$10,$ff,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $80,$80,$80,$80,$80,$80,$80,$80,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
|
||||
db $01,$01,$01,$ff,$10,$10,$10,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $ff,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $fe,$01,$01,$19,$1d,$0d,$01,$01,$00,$ff,$ff,$e7,$e7,$ff,$ff,$ff
|
||||
db $01,$01,$01,$01,$01,$01,$01,$01,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $3f,$7f,$7f,$ff,$ff,$ff,$ff,$ff,$3f,$60,$40,$c0,$80,$80,$80,$80
|
||||
db $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$80,$80,$80,$80,$80,$81,$42,$3c
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$fe,$7c,$00,$00,$00,$00,$00,$01,$82,$7c
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$fe,$7c,$00,$00,$00,$00,$00,$01,$83,$ff
|
||||
db $f8,$fc,$fe,$fe,$ff,$ff,$ff,$ff,$f8,$04,$02,$02,$01,$01,$01,$01
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$01,$01,$01,$01,$01,$81,$42,$3c
|
||||
db $00,$08,$08,$08,$10,$10,$10,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $00,$7f,$7f,$78,$73,$73,$73,$7f,$7f,$80,$a0,$87,$8f,$8e,$8e,$86
|
||||
db $00,$ff,$ff,$3f,$9f,$9f,$9f,$1f,$fe,$01,$05,$c1,$e1,$71,$71,$f1
|
||||
db $7e,$7e,$7f,$7e,$7e,$7f,$7f,$ff,$81,$81,$80,$81,$81,$a0,$80,$ff
|
||||
db $7f,$7f,$ff,$7f,$7f,$ff,$ff,$ff,$f1,$c1,$c1,$81,$c1,$c5,$01,$ff
|
||||
db $7f,$80,$a0,$80,$80,$80,$80,$80,$7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $fe,$01,$05,$01,$01,$01,$01,$01,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $80,$80,$80,$80,$80,$a0,$80,$7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$7f
|
||||
db $01,$01,$01,$01,$01,$05,$01,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe
|
||||
db $00,$00,$00,$00,$fc,$fe,$07,$03,$00,$00,$00,$00,$00,$00,$38,$7c
|
||||
db $11,$39,$11,$01,$01,$01,$01,$01,$fe,$fe,$fe,$7c,$38,$00,$00,$00
|
||||
db $ef,$28,$28,$28,$28,$28,$ef,$00,$20,$e7,$e7,$e7,$e7,$e7,$ef,$00
|
||||
db $fe,$82,$82,$82,$82,$82,$fe,$00,$02,$7e,$7e,$7e,$7e,$7e,$fe,$00
|
||||
db $80,$80,$80,$98,$9c,$8c,$80,$7f,$7f,$7f,$7f,$67,$67,$7f,$7f,$7f
|
||||
db $ff,$ff,$83,$f3,$f3,$f3,$f3,$f3,$ff,$80,$fc,$8c,$8c,$8c,$8c,$8c
|
||||
db $ff,$ff,$f0,$f6,$f6,$f6,$f6,$f6,$ff,$00,$0f,$09,$09,$09,$09,$09
|
||||
db $ff,$ff,$00,$00,$00,$00,$00,$00,$ff,$00,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $ff,$ff,$01,$57,$2f,$57,$2f,$57,$ff,$01,$ff,$a9,$d1,$a9,$d1,$a9
|
||||
db $f3,$f3,$f3,$f3,$f3,$f3,$ff,$3f,$8c,$8c,$8c,$8c,$8c,$8c,$ff,$3f
|
||||
db $f6,$f6,$f6,$f6,$f6,$f6,$ff,$ff,$09,$09,$09,$09,$09,$09,$ff,$ff
|
||||
db $00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $2f,$57,$2f,$57,$2f,$57,$ff,$fc,$d1,$a9,$d1,$a9,$d1,$a9,$ff,$fc
|
||||
db $3c,$3c,$3c,$3c,$3c,$3c,$3c,$3c,$23,$23,$23,$23,$23,$23,$23,$23
|
||||
db $fb,$fb,$fb,$fb,$fb,$fb,$fb,$fb,$04,$04,$04,$04,$04,$04,$04,$04
|
||||
db $bc,$5c,$bc,$5c,$bc,$5c,$bc,$5c,$44,$a4,$44,$a4,$44,$a4,$44,$a4
|
||||
db $1f,$20,$40,$40,$80,$80,$80,$81,$1f,$3f,$7f,$7f,$ff,$ff,$ff,$fe
|
||||
db $ff,$80,$80,$c0,$ff,$ff,$fe,$fe,$ff,$7f,$7f,$3f,$00,$00,$01,$01
|
||||
db $ff,$7f,$7f,$ff,$ff,$07,$03,$03,$ff,$80,$80,$00,$00,$f8,$fc,$fc
|
||||
db $ff,$00,$00,$00,$00,$81,$c3,$ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$00
|
||||
db $f8,$fc,$fe,$fe,$e3,$c1,$81,$81,$f8,$04,$02,$02,$1d,$3f,$7f,$7f
|
||||
db $83,$ff,$ff,$ff,$ff,$ff,$7f,$1f,$fc,$80,$80,$80,$80,$80,$60,$1f
|
||||
db $fc,$fc,$fc,$fc,$fe,$fe,$ff,$ff,$03,$03,$03,$03,$01,$01,$00,$ff
|
||||
db $01,$01,$01,$01,$03,$03,$07,$ff,$fe,$fe,$fe,$fe,$fc,$fc,$f8,$ff
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$ff
|
||||
db $81,$c1,$e3,$ff,$ff,$ff,$ff,$fe,$7f,$3f,$1d,$01,$01,$01,$03,$fe
|
||||
db $ff,$ff,$ff,$ff,$ff,$fb,$b5,$ce,$80,$80,$80,$80,$80,$84,$ca,$b1
|
||||
db $ff,$ff,$ff,$ff,$ff,$df,$ad,$73,$01,$01,$01,$01,$01,$21,$53,$8d
|
||||
db $77,$77,$77,$77,$77,$77,$77,$77,$00,$00,$00,$00,$77,$ff,$ff,$ff
|
||||
db $00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $77,$77,$77,$77,$00,$00,$00,$00,$ff,$ff,$ff,$77,$77,$77,$77,$77
|
||||
db $01,$01,$01,$19,$1d,$0d,$01,$fe,$ff,$ff,$ff,$e7,$e7,$ff,$ff,$fe
|
||||
db $20,$78,$7f,$fe,$fe,$fe,$fe,$fe,$00,$21,$21,$41,$41,$41,$41,$41
|
||||
db $04,$9a,$fa,$fd,$fd,$fd,$fd,$fd,$00,$80,$80,$80,$80,$80,$80,$80
|
||||
db $7e,$38,$21,$00,$01,$00,$01,$00,$21,$21,$01,$01,$01,$01,$01,$01
|
||||
db $fa,$8a,$84,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80
|
||||
db $02,$04,$00,$10,$00,$40,$80,$00,$01,$01,$06,$08,$18,$20,$20,$c0
|
||||
db $0b,$0b,$3b,$0b,$fb,$0b,$0b,$0a,$04,$04,$c4,$f4,$f4,$04,$04,$05
|
||||
db $90,$10,$1f,$10,$1f,$10,$10,$90,$70,$f0,$f0,$ff,$ff,$f0,$f0,$70
|
||||
db $3f,$78,$e7,$cf,$58,$58,$50,$90,$c0,$87,$18,$b0,$e7,$e7,$ef,$ef
|
||||
db $b0,$fc,$e2,$c1,$c1,$83,$8f,$7e,$6f,$43,$5d,$3f,$3f,$7f,$7f,$ff
|
||||
db $fe,$03,$0f,$91,$70,$60,$20,$31,$03,$ff,$f1,$6e,$cf,$df,$ff,$ff
|
||||
db $3f,$3f,$1d,$39,$7b,$f3,$86,$fe,$fd,$fb,$fb,$f7,$f7,$0f,$7f,$ff
|
||||
db $ff,$ff,$ff,$ff,$ff,$80,$80,$ff,$ff,$80,$80,$80,$80,$ff,$ff,$80
|
||||
db $fe,$ff,$ff,$ff,$ff,$03,$03,$ff,$fe,$03,$03,$03,$03,$ff,$ff,$03
|
||||
db $00,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$ff,$00,$00,$00,$00,$ff,$ff
|
||||
db $3c,$fc,$fc,$fc,$fc,$fc,$04,$04,$23,$f3,$0b,$0b,$0b,$07,$ff,$ff
|
||||
db $ff,$ff,$ff,$ff,$80,$ff,$ff,$ff,$80,$80,$80,$80,$ff,$80,$80,$80
|
||||
db $ff,$ff,$ff,$ff,$03,$ff,$ff,$ff,$03,$03,$03,$03,$ff,$03,$03,$03
|
||||
db $ff,$ff,$ff,$ff,$ff,$00,$ff,$ff,$00,$00,$00,$00,$00,$ff,$00,$00
|
||||
db $fc,$fc,$fe,$fe,$fe,$02,$fe,$fe,$07,$07,$03,$03,$03,$ff,$03,$03
|
||||
db $ff,$80,$80,$80,$80,$80,$80,$80,$80,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $ff,$03,$03,$03,$03,$03,$03,$03,$03,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $02,$02,$02,$02,$02,$02,$04,$04,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $80,$80,$aa,$d5,$aa,$ff,$ff,$ff,$ff,$ff,$d5,$aa,$d5,$80,$80,$ff
|
||||
db $03,$03,$ab,$57,$ab,$ff,$ff,$fe,$ff,$ff,$57,$ab,$57,$03,$03,$fe
|
||||
db $00,$55,$aa,$55,$ff,$ff,$ff,$00,$ff,$aa,$55,$aa,$00,$00,$ff,$00
|
||||
db $04,$54,$ac,$5c,$fc,$fc,$fc,$3c,$ff,$af,$57,$ab,$0b,$0b,$f3,$23
|
||||
db $3f,$3f,$3f,$3f,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $7e,$7c,$7c,$78,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $1f,$0f,$0f,$07,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $fe,$fc,$fc,$f8,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $00,$00,$00,$00,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $18,$18,$18,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $07,$1f,$3f,$ff,$7f,$7f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $e1,$f9,$fd,$ff,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $f0,$10,$10,$10,$10,$10,$10,$ff,$00,$e0,$e0,$e0,$e0,$e0,$e0,$e0
|
||||
db $1f,$10,$10,$10,$10,$10,$10,$ff,$00,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
||||
db $92,$92,$92,$fe,$fe,$00,$00,$00,$48,$48,$6c,$00,$00,$00,$fe,$00
|
||||
db $0a,$0a,$3a,$0a,$fb,$0b,$0b,$0b,$05,$05,$c5,$f5,$f4,$04,$04,$04
|
||||
db $90,$90,$9f,$90,$9f,$90,$90,$90,$70,$70,$70,$7f,$7f,$70,$70,$70
|
||||
db $01,$01,$01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $80,$80,$80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $08,$88,$91,$d1,$53,$53,$73,$3f,$ff,$ff,$ff,$ff,$ff,$fe,$be,$ce
|
||||
db $00,$00,$07,$0f,$0c,$1b,$1b,$1b,$00,$00,$00,$00,$03,$04,$04,$04
|
||||
db $00,$00,$e0,$f0,$f0,$f8,$f8,$f8,$00,$00,$60,$30,$30,$98,$98,$98
|
||||
db $1b,$1b,$1b,$1b,$1b,$0f,$0f,$07,$04,$04,$04,$04,$04,$03,$00,$00
|
||||
db $f8,$f8,$f8,$f8,$f8,$f0,$f0,$e0,$98,$98,$98,$98,$98,$30,$30,$60
|
||||
db $f1,$11,$11,$1f,$10,$10,$10,$ff,$0f,$ef,$ef,$ef,$ef,$ef,$ef,$e0
|
||||
db $1f,$10,$10,$f0,$10,$10,$10,$ff,$e0,$ef,$ef,$ef,$ef,$ef,$ef,$0f
|
||||
db $7f,$bf,$df,$ef,$f0,$f0,$f0,$f0,$80,$40,$20,$10,$0f,$0f,$0f,$0f
|
||||
db $f0,$f0,$f0,$f0,$ff,$ff,$ff,$ff,$0f,$0f,$0f,$0f,$1f,$3f,$7f,$ff
|
||||
db $ff,$ff,$ff,$ff,$0f,$0f,$0f,$0f,$01,$03,$07,$0f,$ff,$ff,$ff,$ff
|
||||
db $0f,$0f,$0f,$0f,$f7,$fb,$fd,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $1f,$3f,$7f,$7f,$7f,$ff,$ff,$ff,$1f,$20,$40,$40,$40,$80,$82,$82
|
||||
db $ff,$ff,$ff,$7f,$7f,$7f,$3f,$1e,$82,$80,$a0,$44,$43,$40,$21,$1e
|
||||
db $f8,$fc,$fe,$fe,$fe,$ff,$ff,$ff,$f8,$04,$02,$02,$02,$01,$41,$41
|
||||
db $ff,$ff,$ff,$fe,$fe,$fe,$fc,$78,$41,$01,$05,$22,$c2,$02,$84,$78
|
||||
db $7f,$80,$80,$80,$80,$80,$80,$80,$80,$7f,$7f,$7f,$7f,$7f,$7f,$7f
|
||||
db $de,$61,$61,$61,$71,$5e,$7f,$61,$61,$df,$df,$df,$df,$ff,$c1,$df
|
||||
db $80,$80,$c0,$f0,$bf,$8f,$81,$7e,$7f,$7f,$ff,$3f,$4f,$71,$7f,$ff
|
||||
db $61,$61,$c1,$c1,$81,$81,$83,$fe,$df,$df,$bf,$bf,$7f,$7f,$7f,$7f
|
||||
db $00,$00,$03,$0f,$1f,$3f,$7f,$7f,$00,$00,$03,$0c,$10,$20,$40,$40
|
||||
db $00,$00,$c0,$f0,$f8,$fc,$fe,$fe,$00,$00,$c0,$30,$08,$04,$02,$02
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$80,$80,$80,$80,$80,$80,$80,$80
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$01,$01,$01,$01,$01,$01,$01
|
||||
db $7f,$7f,$7f,$3f,$3f,$1f,$0f,$07,$40,$40,$40,$20,$30,$1c,$0f,$07
|
||||
db $fe,$fe,$fe,$fc,$fc,$f8,$f0,$f0,$02,$02,$02,$04,$0c,$38,$f0,$f0
|
||||
db $0f,$0f,$0f,$0f,$0f,$0f,$07,$0f,$08,$08,$08,$08,$08,$0c,$05,$0a
|
||||
db $f0,$f0,$f0,$f0,$f0,$f0,$e0,$f0,$10,$50,$50,$50,$50,$30,$a0,$50
|
||||
db $81,$c1,$a3,$a3,$9d,$81,$81,$81,$00,$41,$22,$22,$1c,$00,$00,$00
|
||||
db $e3,$f7,$c1,$c1,$c1,$c1,$f7,$e3,$e3,$14,$3e,$3e,$3e,$3e,$14,$e3
|
||||
db $00,$00,$07,$0f,$0c,$1b,$1b,$1b,$ff,$ff,$f8,$f0,$f0,$e0,$e0,$e0
|
||||
db $00,$00,$e0,$f0,$f0,$f8,$f8,$f8,$ff,$ff,$7f,$3f,$3f,$9f,$9f,$9f
|
||||
db $1b,$1b,$1b,$1b,$1b,$0f,$0f,$07,$e0,$e0,$e0,$e0,$e0,$f3,$f0,$f8
|
||||
db $f8,$f8,$f8,$f8,$f8,$f0,$f0,$e0,$9f,$9f,$9f,$9f,$9f,$3f,$3f,$7f
|
||||
db $e0,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$70,$1f,$10,$70,$7f,$7f,$7f
|
||||
db $07,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$03,$f8,$00,$03,$fb,$fb,$fb
|
||||
db $ff,$ff,$ff,$ff,$ff,$fe,$ff,$ef,$7c,$7b,$76,$75,$75,$77,$17,$67
|
||||
db $ff,$df,$ef,$af,$af,$6f,$ef,$e7,$3b,$fb,$7b,$fb,$fb,$f3,$f8,$f3
|
||||
db $1f,$1f,$3f,$3f,$70,$63,$e7,$e5,$0f,$0f,$1f,$1f,$3f,$3c,$78,$7a
|
||||
db $f0,$f0,$f8,$f8,$0c,$c4,$e4,$a6,$f8,$f8,$fc,$fc,$fe,$3e,$1e,$5f
|
||||
db $e9,$e9,$e9,$ef,$e2,$e3,$f0,$ff,$76,$76,$76,$70,$7d,$7c,$7f,$7f
|
||||
db $96,$96,$96,$f6,$46,$c6,$0e,$fe,$6f,$6f,$6f,$0f,$bf,$3f,$ff,$ff
|
||||
db $00,$00,$00,$00,$00,$00,$7e,$3c,$3c,$7e,$7e,$ff,$ff,$ff,$42,$00
|
||||
db $3c,$42,$99,$a1,$a1,$99,$42,$3c,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $0f,$1f,$1f,$3f,$3f,$7f,$7f,$7f,$f0,$e0,$e0,$c0,$c0,$80,$80,$80
|
||||
db $f0,$f8,$f8,$fc,$fc,$fe,$fe,$fe,$0f,$07,$07,$03,$03,$01,$01,$01
|
||||
db $7f,$7f,$3f,$3f,$3f,$3f,$1f,$1f,$80,$80,$c0,$c0,$e0,$f8,$fe,$ff
|
||||
db $fe,$ff,$ff,$ff,$fc,$fc,$fe,$fe,$ff,$7f,$1f,$07,$03,$03,$01,$81
|
||||
db $7f,$7f,$7f,$3f,$3f,$3f,$3f,$1f,$80,$80,$80,$c0,$c0,$e0,$e0,$f0
|
||||
db $fe,$fe,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$03,$07,$07,$0f
|
||||
db $1f,$0f,$0f,$07,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $fe,$fc,$fc,$f8,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $7e,$7e,$7e,$7e,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$03,$07,$07,$0f
|
||||
db $fe,$fe,$fe,$fe,$ff,$ff,$ff,$ff,$01,$01,$01,$01,$01,$01,$01,$01
|
||||
db $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $ff,$ff,$ff,$ff,$fc,$fe,$fe,$7e,$ff,$03,$03,$03,$03,$03,$03,$ff
|
||||
db $ff,$ff,$ff,$ff,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$80,$80,$80,$80,$80,$80,$80,$80
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$07,$03,$01,$01
|
||||
db $7e,$7e,$7f,$7f,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $3f,$3f,$3f,$3f,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $7e,$7c,$7c,$78,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $fe,$fe,$ff,$ff,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $7f,$7f,$3f,$3f,$3f,$3f,$1f,$1f,$80,$80,$c0,$c0,$e0,$f8,$fe,$ff
|
||||
db $3f,$bf,$ff,$ff,$fc,$fc,$fe,$fe,$ff,$7f,$1f,$07,$03,$03,$01,$81
|
||||
db $7f,$7f,$7e,$7e,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $7e,$7e,$7e,$7e,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $81,$c3,$c3,$e7,$e7,$ff,$ff,$ff,$7e,$3c,$3c,$18,$18,$00,$00,$00
|
||||
db $0f,$43,$5b,$53,$31,$19,$0f,$07,$f2,$fe,$fe,$ff,$ff,$ef,$f7,$f8
|
||||
db $c1,$c3,$c6,$84,$fc,$fc,$0e,$02,$bf,$be,$bd,$7b,$7b,$07,$f3,$fd
|
||||
db $10,$20,$22,$ba,$e6,$e1,$c0,$c0,$ff,$ff,$ff,$67,$59,$9e,$bf,$bf
|
||||
db $20,$a6,$54,$26,$20,$c6,$54,$26,$20,$e6,$54,$26,$21,$06,$54,$26
|
||||
db $20,$85,$01,$44,$20,$86,$54,$48,$20,$9a,$01,$49,$20,$a5,$c9,$46
|
||||
db $20,$ba,$c9,$4a,$20,$a6,$0a,$d0,$d1,$d8,$d8,$de,$d1,$d0,$da,$de
|
||||
db $d1,$20,$c6,$0a,$d2,$d3,$db,$db,$db,$d9,$db,$dc,$db,$df,$20,$e6
|
||||
db $0a,$d4,$d5,$d4,$d9,$db,$e2,$d4,$da,$db,$e0,$21,$06,$0a,$d6,$d7
|
||||
db $d6,$d7,$e1,$26,$d6,$dd,$e1,$e1,$21,$26,$14,$d0,$e8,$d1,$d0,$d1
|
||||
db $de,$d1,$d8,$d0,$d1,$26,$de,$d1,$de,$d1,$d0,$d1,$d0,$d1,$26,$21
|
||||
db $46,$14,$db,$42,$42,$db,$42,$db,$42,$db,$db,$42,$26,$db,$42,$db
|
||||
db $42,$db,$42,$db,$42,$26,$21,$66,$46,$db,$21,$6c,$0e,$df,$db,$db
|
||||
db $db,$26,$db,$df,$db,$df,$db,$db,$e4,$e5,$26,$21,$86,$14,$db,$db
|
||||
db $db,$de,$43,$db,$e0,$db,$db,$db,$26,$db,$e3,$db,$e0,$db,$db,$e6
|
||||
db $e3,$26,$21,$a6,$14,$db,$db,$db,$db,$42,$db,$db,$db,$d4,$d9,$26
|
||||
db $db,$d9,$db,$db,$d4,$d9,$d4,$d9,$e7,$21,$c5,$16,$5f,$95,$95,$95
|
||||
db $95,$95,$95,$95,$95,$97,$98,$78,$95,$96,$95,$95,$97,$98,$97,$98
|
||||
db $95,$7a,$21,$ed,$0e,$cf,$01,$09,$08,$05,$24,$17,$12,$17,$1d,$0e
|
||||
db $17,$0d,$18,$22,$4b,$0d,$01,$24,$19,$15,$0a,$22,$0e,$1b,$24,$10
|
||||
db $0a,$16,$0e,$22,$8b,$0d,$02,$24,$19,$15,$0a,$22,$0e,$1b,$24,$10
|
||||
db $0a,$16,$0e,$22,$ec,$04,$1d,$18,$19,$28,$22,$f6,$01,$00,$23,$c9
|
||||
db $56,$55,$23,$e2,$04,$99,$aa,$aa,$aa,$23,$ea,$04,$99,$aa,$aa,$aa
|
|
@ -7,11 +7,14 @@
|
|||
"merlin32": "C:\\Programs\\IIgsXDev\\bin\\Merlin32-1.1.10.exe",
|
||||
"cadius": "C:\\Programs\\IIgsXDev\\bin\\Cadius.exe",
|
||||
"gsport": "C:\\Programs\\gsport\\gsport_0.31\\GSPort.exe",
|
||||
"macros": "C:\\Programs\\BrutalDeluxe\\Merlin32\\Library",
|
||||
"macros": "../../macros",
|
||||
"crossrunner": "C:\\Programs\\Crossrunner\\Crossrunner.exe"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s"
|
||||
"test": "npm run build && npm run build:image && npm run gsport",
|
||||
"gsport": "%npm_package_config_gsport%",
|
||||
"build": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s",
|
||||
"build:image": "build-image.bat %npm_package_config_cadius%"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -667,11 +667,13 @@ GameOverModeValue = 3
|
|||
; .index 8
|
||||
; .mem 8
|
||||
|
||||
org $8000
|
||||
|
||||
;-------------------------------------------------------------------------------------
|
||||
mx %11
|
||||
; External wrapper is responsible for setting the stack
|
||||
|
||||
put chr.s
|
||||
ds $6000
|
||||
SMBStart ENT
|
||||
Start
|
||||
; sei ;pretty standard 6502 type init here
|
||||
; cld
|
||||
|
@ -739,11 +741,11 @@ VRAM_Buffer_Offset
|
|||
db <VRAM_Buffer1_Offset,<VRAM_Buffer2_Offset
|
||||
|
||||
; This is the actual entry point (60 times per second to keep speeed). Uncomment hardware
|
||||
; stuf that doesn't need to be communicated to the GTE wrapper
|
||||
; stuff that doesn't need to be communicated to the GTE wrapper
|
||||
NonMaskableInterrupt
|
||||
; lda Mirror_PPU_CTRL_REG1 ;disable NMIs in mirror reg
|
||||
; and #%01111111 ;save all other bits
|
||||
; sta Mirror_PPU_CTRL_REG1
|
||||
lda Mirror_PPU_CTRL_REG1 ;disable NMIs in mirror reg
|
||||
and #%01111111 ;save all other bits
|
||||
sta Mirror_PPU_CTRL_REG1
|
||||
and #%01111110 ;alter name table address to be $2800
|
||||
sta PPU_CTRL_REG1 ;(essentially $2000) but save other bits
|
||||
lda Mirror_PPU_CTRL_REG2 ;disable OAM and background display by default
|
||||
|
@ -16355,27 +16357,3 @@ BrickShatterEnvData
|
|||
dw NonMaskableInterrupt
|
||||
dw Start
|
||||
dw $fff0 ;unused
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
GTETF4
|
|
@ -0,0 +1,126 @@
|
|||
; Test driver to exercise graphics routines.
|
||||
|
||||
REL
|
||||
DSK MAINSEG
|
||||
|
||||
use Locator.Macs
|
||||
use Load.Macs
|
||||
use Mem.Macs
|
||||
use Misc.Macs
|
||||
use Util.Macs
|
||||
use EDS.GSOS.Macs
|
||||
use GTE.Macs
|
||||
|
||||
mx %00
|
||||
|
||||
tiledata EXT ; tileset buffer
|
||||
;TileSetPalette EXT
|
||||
|
||||
; Keycodes
|
||||
LEFT_ARROW equ $08
|
||||
RIGHT_ARROW equ $15
|
||||
UP_ARROW equ $0B
|
||||
DOWN_ARROW equ $0A
|
||||
|
||||
; Direct page space
|
||||
MyUserId equ 0
|
||||
BankLoad equ 2
|
||||
StartX equ 4
|
||||
StartY equ 6
|
||||
TileMapWidth equ 8
|
||||
TileMapHeight equ 10
|
||||
ScreenWidth equ 12
|
||||
ScreenHeight equ 14
|
||||
MaxGlobalX equ 16
|
||||
MaxGlobalY equ 18
|
||||
MaxBG0X equ 20
|
||||
MaxBG0Y equ 22
|
||||
OldOneSecondCounter equ 26
|
||||
appTmp0 equ 28
|
||||
appTmp1 equ 30
|
||||
appTmp2 equ 32
|
||||
|
||||
phk
|
||||
plb
|
||||
|
||||
sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program
|
||||
tdc
|
||||
sta MyDirectPage ; Keep a copy for the overlay callback
|
||||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_USER_TOOL+ENGINE_MODE_TWO_LAYER
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
pea $0000 ; Set the first two tiles
|
||||
pea $0002
|
||||
pea #^TileData
|
||||
pea #TileData
|
||||
_GTELoadTileSet
|
||||
|
||||
pea $0000
|
||||
pea #^TileSetPalette
|
||||
pea #TileSetPalette
|
||||
_GTESetPalette
|
||||
|
||||
; Fill in the field with a checkboard pattern
|
||||
|
||||
stz appTmp1
|
||||
|
||||
:tloop0 stz appTmp0
|
||||
:tloop1 lda appTmp0 ; X
|
||||
pha
|
||||
pei appTmp1 ; Y
|
||||
eor appTmp1
|
||||
and #$0001
|
||||
pha ; tile ID
|
||||
_GTESetTile
|
||||
|
||||
inc appTmp0
|
||||
lda #40
|
||||
cmp appTmp0
|
||||
bcs :tloop1
|
||||
|
||||
inc appTmp1
|
||||
lda #25
|
||||
cmp appTmp1
|
||||
bcs :tloop0
|
||||
|
||||
; Set up a very specific test. First, we draw a sprite into the sprite plane, and then
|
||||
; leave it alone. We are just testing the ability to merge sprite plane data into
|
||||
; the play field tiles.
|
||||
EvtLoop
|
||||
pha
|
||||
_GTEReadControl
|
||||
pla
|
||||
|
||||
jsr HandleKeys ; Do the generic key handlers
|
||||
|
||||
pea #RENDER_PER_SCANLINE ; Scanline rendering
|
||||
; pea $0000
|
||||
_GTERender
|
||||
|
||||
brl EvtLoop
|
||||
|
||||
; Exit code
|
||||
Exit
|
||||
_GTEShutDown
|
||||
Quit
|
||||
_QuitGS qtRec
|
||||
|
||||
bcs Fatal
|
||||
Fatal brk $00
|
||||
|
||||
qtRec adrl $0000
|
||||
da $00
|
||||
|
||||
; Color palette
|
||||
TileSetPalette dw $0000,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF,$0FFF
|
||||
|
||||
MyDirectPage ds 2
|
||||
|
||||
; Stub
|
||||
SetLimits rts
|
||||
|
||||
PUT ../kfest-2022/StartUp.s
|
||||
PUT Tiles.s
|
|
@ -0,0 +1,10 @@
|
|||
; Thunder Force IV Demo
|
||||
|
||||
TYP $B3 ; S16 file
|
||||
DSK GTETF4
|
||||
XPL
|
||||
|
||||
; Segment #1 -- Main execution block
|
||||
|
||||
ASM App.Main.s
|
||||
SNA Main
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Thunder Force IV scanline demo
|
||||
- q to quit; arrows to scroll, numbers to select screen size
|
||||
- make sure Overlay is present
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
TileData
|
||||
; Reserved space (tile 0 is special...
|
||||
ds 128
|
||||
; Tile ID 1
|
||||
; From image coordinates 0, 0
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
hex ffffffff
|
||||
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
|
@ -0,0 +1 @@
|
|||
GTETF4=Type(B3),AuxType(0000),VersionCreate(70),MinVersion(BE),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.5" tiledversion="1.7.2" name="App.TileSet" tilewidth="8" tileheight="8" tilecount="512" columns="32">
|
||||
<transformations hflip="1" vflip="1" rotate="0" preferuntransformed="0"/>
|
||||
<image source="../tilesets/smb-256-128-4bpp.png" trans="ff00ff" width="256" height="128"/>
|
||||
<tile id="136">
|
||||
<animation>
|
||||
<frame tileid="136" duration="256"/>
|
||||
<frame tileid="138" duration="256"/>
|
||||
<frame tileid="140" duration="256"/>
|
||||
<frame tileid="142" duration="256"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="137">
|
||||
<animation>
|
||||
<frame tileid="137" duration="256"/>
|
||||
<frame tileid="139" duration="256"/>
|
||||
<frame tileid="141" duration="256"/>
|
||||
<frame tileid="143" duration="256"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="168">
|
||||
<animation>
|
||||
<frame tileid="168" duration="256"/>
|
||||
<frame tileid="170" duration="256"/>
|
||||
<frame tileid="172" duration="256"/>
|
||||
<frame tileid="174" duration="256"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="169">
|
||||
<animation>
|
||||
<frame tileid="169" duration="256"/>
|
||||
<frame tileid="171" duration="256"/>
|
||||
<frame tileid="173" duration="256"/>
|
||||
<frame tileid="175" duration="256"/>
|
||||
</animation>
|
||||
</tile>
|
||||
</tileset>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="right-down" width="416" height="30" tilewidth="8" tileheight="8" infinite="0" nextlayerid="4" nextobjectid="2">
|
||||
<editorsettings>
|
||||
<export target="world_1-1.json" format="json"/>
|
||||
</editorsettings>
|
||||
<tileset firstgid="1" source="Overworld.tsx"/>
|
||||
<layer id="1" name="App.TileMapBG0" width="416" height="30">
|
||||
<data encoding="csv">
|
||||
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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,
|
||||
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,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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,153,154,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,153,154,153,154,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,0,0,0,0,0,0,0,0,0,0,153,154,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,153,154,153,154,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,0,0,0,0,0,0,0,0,0,0,153,154,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,153,154,153,154,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,0,0,0,0,0,0,0,0,0,0,0,153,154,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,153,154,153,154,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,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,185,186,186,187,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,185,186,186,186,186,187,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,0,0,0,0,0,0,0,0,185,186,186,187,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,185,186,186,186,186,187,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,0,0,0,0,0,0,0,0,185,186,186,187,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,185,186,186,186,186,187,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,0,0,0,0,0,0,0,0,0,185,186,186,187,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,185,186,186,186,186,187,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,59,60,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,153,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,155,156,157,158,0,0,0,0,0,0,0,0,0,0,0,0,0,153,154,153,154,153,154,0,0,0,0,0,0,0,0,0,0,0,155,156,157,156,157,158,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,153,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,155,156,157,158,0,0,0,0,0,0,0,0,0,0,0,0,0,153,154,153,154,153,154,0,0,0,0,0,0,0,0,0,0,0,155,156,157,156,157,158,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,153,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,155,156,157,158,0,0,0,0,0,0,0,0,0,0,0,0,0,153,154,153,154,153,154,0,0,0,0,0,0,0,0,0,0,0,155,156,157,156,157,158,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,153,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,155,156,157,158,0,0,0,0,0,0,0,0,0,0,0,0,0,153,154,153,154,153,154,0,0,0,0,0,0,0,0,0,0,0,155,156,157,156,157,158,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,55,56,10,0,0,0,0,0,153,154,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,185,186,186,187,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,185,186,186,186,186,186,186,187,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,0,185,186,186,187,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,185,186,186,186,186,186,186,187,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,0,185,186,186,187,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,185,186,186,186,186,186,186,187,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,0,0,185,186,186,187,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,185,186,186,186,186,186,186,187,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,55,10,0,0,0,0,185,186,186,187,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,155,156,157,158,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,155,156,157,156,157,156,157,158,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,0,155,156,157,158,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,155,156,157,156,157,156,157,158,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,0,155,156,157,158,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,155,156,157,156,157,156,157,158,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,0,0,155,156,157,158,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,155,156,157,156,157,156,157,158,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,9,10,0,0,0,0,155,156,157,158,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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,159,160,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,0,0,0,0,0,0,188,188,188,188,188,188,159,160,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,159,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,188,188,188,188,188,188,0,0,0,0,0,0,0,0,188,188,159,160,159,160,188,188,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,191,192,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0,26,26,26,26,26,26,191,192,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,191,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,26,26,26,26,0,0,0,0,0,0,0,0,26,26,191,192,191,192,26,26,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,5,6,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,7,8,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,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,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,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,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,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,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,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,0,0,0,0,0,0,5,6,5,6,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,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,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,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,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,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,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,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,0,0,0,0,0,0,7,8,7,8,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,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,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,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,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,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,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,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,0,0,0,0,5,6,5,6,5,6,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,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,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,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,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,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,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,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,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,0,0,0,0,7,8,7,8,7,8,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,31,32,31,32,31,32,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,159,160,0,0,0,0,0,188,188,159,160,188,188,159,160,188,188,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,11,12,13,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,12,13,14,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,188,188,159,160,188,188,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,188,188,0,0,0,0,0,0,0,0,0,0,188,188,188,188,0,0,0,0,0,0,0,0,159,160,0,0,0,0,159,160,0,0,0,0,159,160,0,0,0,0,0,0,0,0,0,0,188,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,188,188,188,188,0,0,0,0,0,0,0,0,0,0,0,0,5,6,0,0,0,0,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,5,6,0,0,0,0,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,188,188,188,188,159,160,188,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,5,6,5,6,5,6,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,26,26,26,26,26,26,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,191,192,0,0,0,0,0,26,26,191,192,26,26,191,192,26,26,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,15,16,17,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,16,17,18,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,26,26,191,192,26,26,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,26,26,0,0,0,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,0,191,192,0,0,0,0,191,192,0,0,0,0,191,192,0,0,0,0,0,0,0,0,0,0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,8,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,26,26,26,191,192,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,8,7,8,7,8,7,8,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,26,64,26,26,64,26,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,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,11,12,13,14,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,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,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,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,0,0,0,0,0,0,0,0,0,0,5,6,5,6,0,0,0,0,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,5,6,5,6,0,0,0,0,5,6,5,6,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,0,0,0,0,5,6,5,6,5,6,5,6,5,6,5,6,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,0,0,0,0,0,0,0,0,26,64,26,26,64,26,0,0,0,0,
|
||||
0,0,0,0,49,50,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,16,17,18,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,49,50,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,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,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,49,50,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,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,7,8,7,8,0,0,0,0,7,8,7,8,0,0,0,0,0,0,0,0,49,50,0,0,0,0,0,0,7,8,7,8,7,8,0,0,0,0,7,8,7,8,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,0,0,0,0,7,8,7,8,7,8,7,8,7,8,7,8,7,8,0,0,0,0,0,0,0,0,49,50,0,0,0,0,0,0,9,10,0,0,0,0,0,0,31,32,24,25,24,25,24,25,31,32,0,0,
|
||||
0,0,0,48,21,54,51,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,0,11,12,13,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,48,21,54,51,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,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,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,48,21,54,51,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,5,6,5,6,0,0,0,0,5,6,5,6,5,6,0,0,0,0,0,48,21,54,51,0,0,0,5,6,5,6,5,6,5,6,0,0,0,0,5,6,5,6,5,6,0,0,0,0,0,0,0,0,0,0,11,12,13,14,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,11,12,13,14,0,0,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,0,0,0,0,0,0,0,48,21,54,51,0,0,0,0,0,9,10,0,0,0,0,0,0,26,26,26,26,57,58,26,26,26,26,0,0,
|
||||
0,0,48,21,21,21,21,51,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,49,2147483697,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,16,17,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,48,21,21,21,21,51,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,49,2147483697,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,21,21,21,21,51,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,49,2147483697,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,7,8,7,8,7,8,0,0,0,0,7,8,7,8,7,8,0,0,0,0,48,21,21,21,21,51,0,0,7,8,7,8,7,8,7,8,0,0,0,0,7,8,7,8,7,8,0,0,0,0,0,0,49,2147483697,0,0,15,16,17,18,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,15,16,17,18,0,0,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,0,0,0,0,0,0,48,21,21,21,21,51,0,0,0,0,9,10,0,0,0,0,0,0,26,26,26,26,64,64,26,26,26,26,0,0,
|
||||
0,48,21,54,21,21,54,21,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,35,34,35,34,35,0,0,0,48,21,54,2147483696,0,0,0,0,0,0,0,0,0,0,0,34,35,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,34,35,34,35,0,0,0,0,19,20,21,22,0,48,21,54,21,21,54,21,51,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,34,35,34,35,34,35,0,0,0,48,21,54,2147483696,0,0,0,0,0,0,0,0,0,0,0,34,35,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,34,35,34,35,0,0,0,0,0,0,0,0,0,48,21,54,21,21,54,21,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,35,34,35,34,35,0,0,0,48,21,54,2147483696,0,0,0,0,0,0,0,0,0,0,0,34,35,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,5,6,5,6,5,6,5,6,34,35,34,35,5,6,5,6,5,6,5,6,0,48,21,54,21,21,54,21,5,6,5,6,5,6,5,6,5,6,0,0,0,0,5,6,5,6,5,6,5,6,0,0,0,48,21,54,2147483696,0,19,20,21,22,0,0,0,0,0,0,34,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,5,6,0,0,0,0,0,48,21,54,21,21,54,21,51,0,0,0,5,6,0,0,0,0,0,0,26,26,26,26,64,64,26,26,26,26,0,0,
|
||||
48,21,21,21,21,21,21,21,21,51,0,0,0,0,0,0,0,0,0,0,0,0,0,36,37,37,37,37,37,37,38,0,48,21,21,21,21,2147483696,0,0,0,0,0,0,0,0,0,36,37,37,38,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,36,37,37,37,37,38,0,0,0,19,20,21,22,48,21,21,21,21,21,21,21,21,51,0,0,0,0,0,0,0,0,19,20,21,22,0,36,37,37,37,37,37,37,38,0,48,21,21,21,21,2147483696,0,0,0,0,0,0,0,0,0,36,37,37,38,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,36,37,37,37,37,38,0,0,0,0,0,0,0,48,21,21,21,21,21,21,21,21,51,0,0,0,0,0,0,0,0,0,0,0,0,0,36,37,37,37,37,37,37,38,0,48,21,21,21,21,2147483696,0,0,0,0,0,0,0,0,0,36,37,37,38,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,7,8,7,8,7,8,7,8,37,37,37,37,7,8,7,8,7,8,7,8,48,21,21,21,21,21,21,21,7,8,7,8,7,8,7,8,7,8,0,0,0,0,7,8,7,8,7,8,7,8,38,0,48,21,21,21,21,2147483696,19,20,21,22,0,0,0,0,0,36,37,37,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,20,21,22,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,0,0,0,0,48,21,21,21,21,21,21,21,21,51,0,0,7,8,0,0,0,0,0,0,26,26,26,26,64,64,26,26,26,26,0,0,
|
||||
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
|
||||
3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,0,0,0,0,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,0,0,0,0,0,0,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,0,0,0,0,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,
|
||||
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
|
||||
3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,0,0,0,0,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,0,0,0,0,0,0,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,0,0,0,0,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4,3,4
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
|
@ -0,0 +1,17 @@
|
|||
echo off
|
||||
|
||||
REM Copy all of the assets into the ProDOS image for emulator testing
|
||||
REM
|
||||
REM Pass the path of the Cadius tool as the first argument (%1)
|
||||
|
||||
set CADIUS="%1"
|
||||
set IMAGE="..\\..\\emu\\Target.2mg"
|
||||
set FOLDER="/GTEDEV/TF4"
|
||||
|
||||
REM Cadius does not overwrite files, so clear the root folder first
|
||||
%CADIUS% DELETEFOLDER %IMAGE% %FOLDER%
|
||||
%CADIUS% CREATEFOLDER %IMAGE% %FOLDER%
|
||||
|
||||
REM Now copy files and folders as needed
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\GTETF4
|
||||
%CADIUS% ADDFILE %IMAGE% %FOLDER% ..\..\src\Tool160
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "tf4-demo",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"config": {
|
||||
"merlin32": "C:\\Programs\\IIgsXDev\\bin\\Merlin32-1.1.10.exe",
|
||||
"cadius": "C:\\Programs\\IIgsXDev\\bin\\Cadius.exe",
|
||||
"gsport": "C:\\Programs\\gsport\\gsport_0.31\\GSPort.exe",
|
||||
"macros": "../../macros",
|
||||
"crossrunner": "C:\\Programs\\Crossrunner\\Crossrunner.exe",
|
||||
"png2iigs": "../../tools/png2iigs.js",
|
||||
"tiled2iigs": "../../tools/tiled2iigs.js"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "npm run build && npm run build:image && npm run gsport",
|
||||
"gsport": "%npm_package_config_gsport%",
|
||||
"debug": "%npm_package_config_crossrunner% GTETestSprites -Source GTETestSprites_S02_MAINSEG_Output.txt -Debug -CompatibilityLayer",
|
||||
"build:all": "npm run build:tiles && npm run build:map && npm run build:tool && npm run build:sys16 && npm run build:image",
|
||||
"build:map": "node %npm_package_config_tiled2iigs% ./assets/tiled/world_1-1.json --empty-tile 33 --no-gen-tiles --output-dir ./gen",
|
||||
"build:map:masked": "node %npm_package_config_tiled2iigs% ./assets/tiled/world_1-1.json --force-masked --empty-tile 33 --no-gen-tiles --output-dir ./gen",
|
||||
"build:tiles": "node %npm_package_config_png2iigs% ./assets/tilesets/smb-256-128-4bpp.png --max-tiles 360 --as-tile-data --transparent-color FF00FF --background-color 6B8CFF --verbose > ./gen/App.TileSet.s",
|
||||
"build:sys16": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s",
|
||||
"build": "npm run build:tool && npm run build:sys16",
|
||||
"build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../src/Master.s",
|
||||
"build:image": "build-image.bat %npm_package_config_cadius%"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/lscharen/iigs-game-engine.git"
|
||||
},
|
||||
"author": "Lucas Scharenbroich",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/lscharen/iigs-game-engine/issues"
|
||||
},
|
||||
"homepage": "https://github.com/lscharen/iigs-game-engine#readme",
|
||||
"devDependencies": {
|
||||
"pngjs": "^6.0.0",
|
||||
"string-builder": "^0.1.8",
|
||||
"watch": "latest",
|
||||
"xml2json": "^0.12.0"
|
||||
}
|
||||
}
|
|
@ -24,40 +24,67 @@ Selected equ 10
|
|||
Flips equ 12
|
||||
DTile equ 14
|
||||
Tmp2 equ 16
|
||||
ScreenWidth equ 18
|
||||
ScreenHeight equ 20
|
||||
SpriteFlags equ 22
|
||||
frameCount equ 24
|
||||
OldOneSecondCounter equ 26
|
||||
SpriteAddr equ 28
|
||||
RenderMode equ 30
|
||||
|
||||
; Control modes
|
||||
DefaultMode equ RENDER_WITH_SHADOWING
|
||||
SlowSprites equ 0
|
||||
|
||||
; Typical init
|
||||
phk
|
||||
plb
|
||||
|
||||
sta MyUserId ; GS/OS passes the memory manager user ID for the application into the program
|
||||
tdc
|
||||
sta MyDirectPage ; Keep a copy for the overlay callback
|
||||
|
||||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
lda #ENGINE_MODE_USER_TOOL ; +ENGINE_MODE_TWO_LAYER
|
||||
jsr GTEStartUp ; Load and install the GTE User Tool
|
||||
|
||||
; Init local variables
|
||||
|
||||
stz frameCount
|
||||
|
||||
lda #DefaultMode
|
||||
sta RenderMode
|
||||
|
||||
; Initialize the graphics screen to a 256x160 playfield
|
||||
|
||||
pea #320
|
||||
pea #160
|
||||
pea #200
|
||||
_GTESetScreenMode
|
||||
|
||||
; Load a tileset
|
||||
|
||||
pea 0
|
||||
pea 360
|
||||
pea #^TSZelda
|
||||
pea #TSZelda
|
||||
_GTELoadTileSet
|
||||
|
||||
; Set the palette
|
||||
ldx #11*2
|
||||
:ploop
|
||||
lda palette,x
|
||||
stal $E19E00,x
|
||||
dex
|
||||
dex
|
||||
bpl :ploop
|
||||
bra sprt
|
||||
pea $0000
|
||||
pea #^palette
|
||||
pea #palette
|
||||
_GTESetPalette
|
||||
|
||||
palette dw $0000,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$023E
|
||||
sprt
|
||||
jsr SetLimits
|
||||
|
||||
lda #193 ; Tile ID of '0'
|
||||
jsr InitOverlay ; Initialize the status bar
|
||||
pha
|
||||
_GTEGetSeconds
|
||||
pla
|
||||
sta OldOneSecondCounter
|
||||
jsr UdtOverlay
|
||||
|
||||
; Create stamps for the sprites we are going to use
|
||||
HERO_SPRITE equ SPRITE_16X16+1
|
||||
|
@ -66,25 +93,38 @@ HERO_SPRITE equ SPRITE_16X16+1
|
|||
pea VBUFF_SPRITE_START ; vbuff address
|
||||
_GTECreateSpriteStamp
|
||||
|
||||
DO SlowSprites
|
||||
lda #SPRITE_16X16
|
||||
sta SpriteFlags
|
||||
lda #VBUFF_SPRITE_START
|
||||
sta SpriteAddr
|
||||
ELSE
|
||||
lda #SPRITE_16X16+SPRITE_COMPILED
|
||||
sta SpriteFlags
|
||||
|
||||
pha ; Space for result
|
||||
pea SPRITE_16X16
|
||||
pea VBUFF_SPRITE_START
|
||||
_GTECompileSpriteStamp
|
||||
pla
|
||||
sta SpriteAddr
|
||||
FIN
|
||||
|
||||
; Create sprites
|
||||
stz Tmp0
|
||||
stz Tmp1
|
||||
stz Tmp1 ; Slot number
|
||||
|
||||
ldx Tmp0
|
||||
:sloop
|
||||
pea HERO_SPRITE ; sprite id
|
||||
pei Tmp1 ; Put the sprite in this slot
|
||||
pei SpriteFlags ; with these flags (h/v flip)
|
||||
pei SpriteAddr
|
||||
lda PlayerX,x
|
||||
pha
|
||||
lda PlayerY,x
|
||||
pha
|
||||
pei Tmp1
|
||||
_GTEAddSprite
|
||||
|
||||
pei Tmp1 ; update the sprite in this slot
|
||||
pea $0000 ; with these flags (h/v flip)
|
||||
pea VBUFF_SPRITE_START ; and use this stamp
|
||||
_GTEUpdateSprite
|
||||
|
||||
inc Tmp1
|
||||
ldx Tmp0
|
||||
inx
|
||||
|
@ -95,80 +135,13 @@ HERO_SPRITE equ SPRITE_16X16+1
|
|||
|
||||
; Manually fill in the 41x26 tiles of the TileStore with a test pattern of trees
|
||||
|
||||
; lda #TILE_DYN_BIT+TILE_PRIORITY_BIT+0 ; fill the screen the the dynamic tile slot 0
|
||||
lda #TILE_DYN_BIT+0 ; fill the screen the the dynamic tile slot 0
|
||||
jsr _fillTileStore
|
||||
; brl :no_trees
|
||||
|
||||
ldx #0
|
||||
ldy #0
|
||||
jsr _drawTree
|
||||
|
||||
ldx #3
|
||||
ldy #0
|
||||
jsr _drawTreeH
|
||||
|
||||
ldx #0
|
||||
ldy #3
|
||||
jsr _drawTreeV
|
||||
|
||||
ldx #3
|
||||
ldy #3
|
||||
jsr _drawTreeHV
|
||||
|
||||
ldx #9
|
||||
ldy #0
|
||||
jsr _drawTree
|
||||
|
||||
ldx #9
|
||||
ldy #3
|
||||
jsr _drawTree
|
||||
|
||||
ldx #12
|
||||
ldy #0
|
||||
jsr _drawTree
|
||||
|
||||
ldx #12
|
||||
ldy #3
|
||||
jsr _drawTree
|
||||
|
||||
ldx #6
|
||||
ldy #0
|
||||
jsr _drawTreeFront
|
||||
|
||||
ldx #6
|
||||
ldy #3
|
||||
jsr _drawTreeFront
|
||||
|
||||
ldx #6
|
||||
ldy #6
|
||||
jsr _drawTreeFront
|
||||
|
||||
ldx #3
|
||||
ldy #6
|
||||
jsr _drawTreeFront
|
||||
|
||||
ldx #0
|
||||
ldy #6
|
||||
jsr _drawTreeFront
|
||||
:no_trees
|
||||
; Set up the dynamic tile
|
||||
lda #65
|
||||
sta DTile
|
||||
|
||||
pei DTile
|
||||
pea $0000
|
||||
_GTECopyTileToDynamic ; Copy DTile into the first dynamic tile slot
|
||||
|
||||
; Initialize the frame counter
|
||||
|
||||
stz FrameCount
|
||||
|
||||
; Set the screen coordinates
|
||||
|
||||
lda #128
|
||||
lda #0
|
||||
sta ScreenX
|
||||
lda #128
|
||||
lda #0
|
||||
sta ScreenY
|
||||
|
||||
stz Selected
|
||||
|
@ -179,309 +152,178 @@ HERO_SPRITE equ SPRITE_16X16+1
|
|||
pha ; space for result, with pattern
|
||||
_GTEReadControl
|
||||
pla
|
||||
and #$00FF
|
||||
cmp #'q'
|
||||
bne :2
|
||||
brl :exit
|
||||
:2
|
||||
; cmp KeyState
|
||||
; beq :evt_loop
|
||||
; sta KeyState
|
||||
; cmp #0
|
||||
; beq :evt_loop
|
||||
|
||||
; cmp #' '
|
||||
; bne :evt_loop ; only advance one frame at a time
|
||||
; brl :next
|
||||
|
||||
:3
|
||||
cmp #'1'
|
||||
bcc :3a
|
||||
cmp #'9'
|
||||
bcs :3a
|
||||
sec
|
||||
sbc #'1'
|
||||
asl
|
||||
sta Selected
|
||||
brl :next
|
||||
|
||||
:3a
|
||||
cmp #'r'
|
||||
bne :3b
|
||||
lda Flips
|
||||
clc
|
||||
adc #SPRITE_HFLIP
|
||||
and #SPRITE_VFLIP+SPRITE_HFLIP
|
||||
sta Flips
|
||||
|
||||
pei Selected ; update the sprite in this slot
|
||||
pei Flips ; with these flags (h/v flip)
|
||||
pea VBUFF_SPRITE_START ; and use this stamp
|
||||
_GTEUpdateSprite
|
||||
|
||||
:3b
|
||||
cmp #'x'
|
||||
bne :3d
|
||||
ldx Selected
|
||||
lda PlayerX,x
|
||||
clc
|
||||
adc PlayerU,x
|
||||
sta PlayerX,x
|
||||
|
||||
lda PlayerY,x
|
||||
clc
|
||||
adc PlayerV,x
|
||||
sta PlayerY,x
|
||||
brl :next
|
||||
:3d
|
||||
cmp #'z'
|
||||
bne :3e
|
||||
ldx Selected
|
||||
lda PlayerX,x
|
||||
sec
|
||||
sbc PlayerU,x
|
||||
sta PlayerX,x
|
||||
|
||||
lda PlayerY,x
|
||||
sec
|
||||
sbc PlayerV,x
|
||||
sta PlayerY,x
|
||||
brl :next
|
||||
:3e
|
||||
cmp #'s'
|
||||
bne :4
|
||||
ldx Selected
|
||||
inc PlayerY,x
|
||||
brl :next
|
||||
:4
|
||||
cmp #'w'
|
||||
bne :5
|
||||
ldx Selected
|
||||
dec PlayerY,x
|
||||
brl :next
|
||||
:5
|
||||
cmp #'d'
|
||||
bne :6
|
||||
ldx Selected
|
||||
inc PlayerX,x
|
||||
brl :next
|
||||
:6
|
||||
cmp #'a'
|
||||
bne :7
|
||||
ldx Selected
|
||||
dec PlayerX,x
|
||||
brl :next
|
||||
:7
|
||||
cmp #$15 ; left = $08, right = $15, up = $0B, down = $0A
|
||||
bne :8
|
||||
inc ScreenX
|
||||
bra :next
|
||||
|
||||
:8 cmp #$08
|
||||
bne :9
|
||||
dec ScreenX
|
||||
brl :next
|
||||
|
||||
:9 cmp #$0B
|
||||
bne :10
|
||||
inc ScreenY
|
||||
brl :next
|
||||
|
||||
:10 cmp #$0A
|
||||
bne :11
|
||||
dec ScreenY
|
||||
brl :next
|
||||
|
||||
:11 cmp #'y'
|
||||
bne :12
|
||||
lda DTile
|
||||
inc
|
||||
jsr HandleKeys ; Do the generic key handlers
|
||||
bcs :do_more
|
||||
brl :do_render
|
||||
:do_more
|
||||
and #$007F
|
||||
sta DTile
|
||||
pha
|
||||
pea $0000
|
||||
_GTECopyTileToDynamic
|
||||
brl :next
|
||||
cmp #'a' ; Put in single-step advance mode
|
||||
bne :skip_a
|
||||
:a_loop
|
||||
jsr :next_frame
|
||||
:a_spin
|
||||
pha ; space for result, with pattern
|
||||
_GTEReadControl
|
||||
pla
|
||||
bit #PAD_KEY_DOWN
|
||||
bne :a_spin
|
||||
and #$007F
|
||||
cmp #'r' ; resume?
|
||||
beq :do_render
|
||||
cmp #'s'
|
||||
beq :toggle_sort
|
||||
cmp #'a'
|
||||
beq :a_loop
|
||||
bra :a_spin
|
||||
:toggle_sort lda RenderMode
|
||||
eor #RENDER_SPRITES_SORTED
|
||||
sta RenderMode
|
||||
pei RenderMode
|
||||
_GTERender
|
||||
bra :a_spin
|
||||
:skip_a
|
||||
|
||||
:do_render jsr :next_frame
|
||||
brl :evt_loop
|
||||
|
||||
:12 cmp #'f'
|
||||
bne :13
|
||||
pea $0000
|
||||
_GTEFillTileStore
|
||||
brl :next
|
||||
|
||||
:13 cmp #'m'
|
||||
bne :next
|
||||
_GTERefresh
|
||||
|
||||
:next
|
||||
; inc ScreenX
|
||||
:next_frame
|
||||
jsr _moveSprites
|
||||
|
||||
inc ScreenX
|
||||
inc ScreenY
|
||||
pei ScreenX
|
||||
pei ScreenY
|
||||
_GTESetBG0Origin
|
||||
|
||||
; brl no_animate
|
||||
|
||||
stz Tmp0
|
||||
stz Tmp1
|
||||
|
||||
ldx Tmp0
|
||||
loopX
|
||||
lda PlayerX,x
|
||||
clc
|
||||
adc PlayerU,x
|
||||
sta PlayerX,x
|
||||
bpl is_posx
|
||||
cmp #-15
|
||||
bcs do_y
|
||||
lda PlayerU,x
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerU,x
|
||||
bra do_y
|
||||
is_posx cmp #128
|
||||
bcc do_y
|
||||
lda PlayerU,x
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerU,x
|
||||
|
||||
do_y
|
||||
lda PlayerY,x
|
||||
clc
|
||||
adc PlayerV,x
|
||||
sta PlayerY,x
|
||||
bpl is_posy
|
||||
cmp #-15
|
||||
bcs do_z
|
||||
lda PlayerV,x
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerV,x
|
||||
bra do_z
|
||||
is_posy cmp #160
|
||||
bcc do_z
|
||||
lda PlayerV,x
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerV,x
|
||||
do_z
|
||||
inc Tmp1
|
||||
ldx Tmp0
|
||||
inx
|
||||
inx
|
||||
stx Tmp0
|
||||
cpx #MAX_SPRITES*2
|
||||
bcc loopX
|
||||
|
||||
no_animate
|
||||
stz Tmp0
|
||||
stz Tmp1
|
||||
ldx Tmp0
|
||||
loopY
|
||||
pei Tmp1
|
||||
lda PlayerX,x
|
||||
pha
|
||||
lda PlayerY,x
|
||||
pha
|
||||
_GTEMoveSprite
|
||||
|
||||
inc Tmp1
|
||||
ldx Tmp0
|
||||
inx
|
||||
inx
|
||||
stx Tmp0
|
||||
cpx #MAX_SPRITES*2
|
||||
bcc loopY
|
||||
|
||||
pei RenderMode
|
||||
_GTERender
|
||||
inc FrameCount
|
||||
|
||||
; Debug stuff
|
||||
; Update the performance counters
|
||||
|
||||
inc frameCount
|
||||
pha
|
||||
_GTEGetSeconds
|
||||
pla
|
||||
cmp LastSecond
|
||||
beq :no_fps
|
||||
sta LastSecond
|
||||
|
||||
lda FrameCount
|
||||
ldx #0
|
||||
ldy #$FFFF
|
||||
jsr DrawWord
|
||||
|
||||
stz FrameCount
|
||||
:no_fps
|
||||
|
||||
; tdc
|
||||
; ldx #160*32
|
||||
; jsr DrawWord
|
||||
|
||||
brl :evt_loop
|
||||
cmp OldOneSecondCounter
|
||||
beq :noudt
|
||||
sta OldOneSecondCounter
|
||||
jsr UdtOverlay
|
||||
stz frameCount
|
||||
:noudt
|
||||
rts
|
||||
|
||||
; Shut down everything
|
||||
:exit
|
||||
Exit
|
||||
_GTEShutDown
|
||||
_QuitGS qtRec
|
||||
qtRec adrl $0000
|
||||
da $00
|
||||
|
||||
; Array of sprite positions and velocities
|
||||
DO 1
|
||||
PlayerX dw 8,14,29,34,45,67,81,83,92,101,39,22,7,74,111,9
|
||||
PlayerY dw 72,24,13,56,35,72,23,8,93,123,134,87,143,14,46,65
|
||||
PlayerU dw 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4
|
||||
PlayerV dw 1,1,1,1,2,2,2,4,3,3,3,3,4,4,4,4
|
||||
ELSE
|
||||
PlayerX dw 2,12,22,32,42,52,62,72,2,12,22,32,42,52,62,72,
|
||||
PlayerY dw 24,24,24,24,24,24,24,24,44,44,44,44,44,44,44,44
|
||||
PlayerU dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
PlayerV dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
FIN
|
||||
_moveSprites
|
||||
stz Tmp0
|
||||
:loop
|
||||
ldx Tmp0
|
||||
|
||||
; Load the GTE User Tool and install it
|
||||
GTEStartUp
|
||||
pea $0000
|
||||
_LoaderStatus
|
||||
lda PlayerX,x
|
||||
clc
|
||||
adc PlayerU,x
|
||||
sta PlayerX,x
|
||||
|
||||
bpl :chk_xpos
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerX,x
|
||||
bra :rev_x
|
||||
:chk_xpos
|
||||
cmp ScreenWidth
|
||||
bcc :ok_x
|
||||
sbc ScreenWidth
|
||||
eor #$FFFF
|
||||
inc
|
||||
clc
|
||||
adc ScreenWidth
|
||||
sta PlayerX,x
|
||||
|
||||
:rev_x
|
||||
lda PlayerU,x ; reverse the velocity
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerU,x
|
||||
:ok_x
|
||||
|
||||
lda PlayerY,x
|
||||
clc
|
||||
adc PlayerV,x
|
||||
sta PlayerY,x
|
||||
bpl :chk_ypos
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerY,x
|
||||
bra :rev_y
|
||||
:chk_ypos
|
||||
cmp ScreenHeight
|
||||
bcc :ok_y
|
||||
sbc ScreenHeight
|
||||
eor #$FFFF
|
||||
inc
|
||||
clc
|
||||
adc ScreenHeight
|
||||
sta PlayerY,x
|
||||
|
||||
:rev_y
|
||||
lda PlayerV,x ; reverse the velocity
|
||||
eor #$FFFF
|
||||
inc
|
||||
sta PlayerV,x
|
||||
|
||||
:ok_y
|
||||
txa
|
||||
lsr
|
||||
pha
|
||||
lda PlayerX,x
|
||||
pha
|
||||
lda PlayerY,x
|
||||
pha
|
||||
_GTEMoveSprite
|
||||
|
||||
lda Tmp0
|
||||
inc
|
||||
inc
|
||||
sta Tmp0
|
||||
cmp #2*MAX_SPRITES
|
||||
bcc :loop
|
||||
rts
|
||||
|
||||
; Called by StartUp function callbacks when the screen size changes
|
||||
SetLimits
|
||||
pha ; Allocate space for x, y, width, height
|
||||
pha
|
||||
pha
|
||||
pha
|
||||
_GTEGetScreenInfo
|
||||
pla
|
||||
|
||||
pea $0000
|
||||
pea $0000
|
||||
pea $0000
|
||||
pea $0000
|
||||
pea $0000 ; result space
|
||||
|
||||
lda MyUserId
|
||||
pha
|
||||
|
||||
pea #^ToolPath
|
||||
pea #ToolPath
|
||||
pea $0001 ; do not load into special memory
|
||||
_InitialLoad
|
||||
bcc :ok1
|
||||
brk $01
|
||||
|
||||
:ok1
|
||||
ply
|
||||
pla ; Address of the loaded tool
|
||||
plx
|
||||
ply
|
||||
ply
|
||||
|
||||
pea $8000 ; User toolset
|
||||
pea $00A0 ; Set the tool set number
|
||||
phx
|
||||
pha ; Address of function pointer table
|
||||
_SetTSPtr
|
||||
bcc :ok2
|
||||
brk $02
|
||||
|
||||
:ok2
|
||||
clc ; Give GTE a page of direct page memory
|
||||
tdc
|
||||
adc #$0100
|
||||
pha
|
||||
pea #ENGINE_MODE_DYN_TILES+ENGINE_MODE_TWO_LAYER ; Enable Dynamic Tiles and Two Layer
|
||||
lda MyUserId ; Pass the userId for memory allocation
|
||||
pha
|
||||
_GTEStartUp
|
||||
bcc :ok3
|
||||
brk $03
|
||||
|
||||
:ok3
|
||||
pla ; Discard screen corner
|
||||
pla
|
||||
sec
|
||||
sbc #8
|
||||
sta ScreenWidth ; Pre-adjust to keep sprites on the visible playfield (for compiled sprites)
|
||||
pla
|
||||
sec
|
||||
sbc #16
|
||||
sta ScreenHeight
|
||||
rts
|
||||
|
||||
_fillTileStore
|
||||
|
@ -490,25 +332,22 @@ _fillTileStore
|
|||
:oloop
|
||||
stz Tmp1
|
||||
:iloop
|
||||
pei Tmp1
|
||||
pei Tmp0
|
||||
pei Tmp2
|
||||
_GTESetTile
|
||||
|
||||
lda Tmp2
|
||||
eor #TILE_PRIORITY_BIT
|
||||
sta Tmp2
|
||||
ldx Tmp1
|
||||
ldy Tmp0
|
||||
jsr _drawTree
|
||||
|
||||
lda Tmp1
|
||||
inc
|
||||
clc
|
||||
adc #2
|
||||
sta Tmp1
|
||||
cmp #41
|
||||
cmp #40
|
||||
bcc :iloop
|
||||
|
||||
lda Tmp0
|
||||
inc
|
||||
clc
|
||||
adc #2
|
||||
sta Tmp0
|
||||
cmp #26
|
||||
cmp #25
|
||||
bcc :oloop
|
||||
rts
|
||||
|
||||
|
@ -645,10 +484,12 @@ _drawTreeHV
|
|||
_GTESetTile
|
||||
rts
|
||||
|
||||
MyDirectPage ds 2
|
||||
MyUserId ds 2
|
||||
ToolPath str '1/Tool160'
|
||||
FrameCount ds 2
|
||||
LastSecond dw 0
|
||||
palette dw $0000,$08C1,$0C41,$0F93,$0777,$0FDA,$00A0,$0000,$0D20,$0FFF,$0FD7,$0F59,$0000,$01CE,$0EDA,$0EEE
|
||||
|
||||
PUT App.Msg.s
|
||||
PUT font.s
|
||||
PUT ../kfest-2022/StartUp.s
|
||||
PUT ../shell/Overlay.s
|
||||
|
||||
; PUT App.Msg.s
|
||||
; PUT font.s
|
||||
|
|
File diff suppressed because it is too large
Load Diff
69
docs/Gemfile
69
docs/Gemfile
|
@ -1,34 +1,35 @@
|
|||
source "https://rubygems.org"
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
# gem "jekyll", "~> 4.2.2"
|
||||
gem "github-pages", "~> 203", group: :jekyll_plugins
|
||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||
gem "minima", "~> 2.5"
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
# gem "github-pages", group: :jekyll_plugins
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-feed", "~> 0.12"
|
||||
end
|
||||
|
||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
# and associated library.
|
||||
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||
gem "tzinfo", "~> 1.2"
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
|
||||
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
|
||||
# do not have a Java counterpart.
|
||||
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
|
||||
source "https://rubygems.org"
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
#gem "jekyll", "~> 4.3.2"
|
||||
gem "github-pages", "~> 223", group: :jekyll_plugins
|
||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||
gem "minima", "~> 2.5"
|
||||
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
# gem "github-pages", group: :jekyll_plugins
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-feed", "~> 0.12"
|
||||
end
|
||||
|
||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
# and associated library.
|
||||
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||
gem "tzinfo", "~> 1.2"
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
|
||||
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
|
||||
# do not have a Java counterpart.
|
||||
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.5)
|
||||
activesupport (6.0.6.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.4)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
|
@ -16,105 +16,88 @@ GEM
|
|||
colorator (1.1.0)
|
||||
commonmarker (0.17.13)
|
||||
ruby-enum (~> 0.5)
|
||||
concurrent-ruby (1.1.10)
|
||||
dnsruby (1.61.9)
|
||||
simpleidn (~> 0.1)
|
||||
concurrent-ruby (1.2.2)
|
||||
dnsruby (1.70.0)
|
||||
simpleidn (~> 0.2.1)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
ethon (0.15.0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
eventmachine (1.2.7-x64-mingw32)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.8.1)
|
||||
faraday (1.10.0)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-httpclient (~> 1.0)
|
||||
faraday-multipart (~> 1.0)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.0)
|
||||
faraday-patron (~> 1.0)
|
||||
faraday-rack (~> 1.0)
|
||||
faraday-retry (~> 1.0)
|
||||
faraday (2.7.4)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-multipart (1.0.4)
|
||||
multipart-post (~> 2)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
faraday-retry (1.0.3)
|
||||
ffi (1.15.5-x64-mingw32)
|
||||
faraday-net_http (3.0.2)
|
||||
ffi (1.15.5)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
github-pages (203)
|
||||
github-pages-health-check (= 1.16.1)
|
||||
jekyll (= 3.8.5)
|
||||
github-pages (223)
|
||||
github-pages-health-check (= 1.17.9)
|
||||
jekyll (= 3.9.0)
|
||||
jekyll-avatar (= 0.7.0)
|
||||
jekyll-coffeescript (= 1.1.1)
|
||||
jekyll-commonmark-ghpages (= 0.1.6)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.13.0)
|
||||
jekyll-feed (= 0.15.1)
|
||||
jekyll-gist (= 1.5.0)
|
||||
jekyll-github-metadata (= 2.12.1)
|
||||
jekyll-mentions (= 1.5.1)
|
||||
jekyll-github-metadata (= 2.13.0)
|
||||
jekyll-include-cache (= 0.2.1)
|
||||
jekyll-mentions (= 1.6.0)
|
||||
jekyll-optional-front-matter (= 0.3.2)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-readme-index (= 0.3.0)
|
||||
jekyll-redirect-from (= 0.15.0)
|
||||
jekyll-redirect-from (= 0.16.0)
|
||||
jekyll-relative-links (= 0.6.1)
|
||||
jekyll-remote-theme (= 0.4.1)
|
||||
jekyll-remote-theme (= 0.4.3)
|
||||
jekyll-sass-converter (= 1.5.2)
|
||||
jekyll-seo-tag (= 2.6.1)
|
||||
jekyll-seo-tag (= 2.7.1)
|
||||
jekyll-sitemap (= 1.4.0)
|
||||
jekyll-swiss (= 1.0.0)
|
||||
jekyll-theme-architect (= 0.1.1)
|
||||
jekyll-theme-cayman (= 0.1.1)
|
||||
jekyll-theme-dinky (= 0.1.1)
|
||||
jekyll-theme-hacker (= 0.1.1)
|
||||
jekyll-theme-leap-day (= 0.1.1)
|
||||
jekyll-theme-merlot (= 0.1.1)
|
||||
jekyll-theme-midnight (= 0.1.1)
|
||||
jekyll-theme-minimal (= 0.1.1)
|
||||
jekyll-theme-modernist (= 0.1.1)
|
||||
jekyll-theme-primer (= 0.5.4)
|
||||
jekyll-theme-slate (= 0.1.1)
|
||||
jekyll-theme-tactile (= 0.1.1)
|
||||
jekyll-theme-time-machine (= 0.1.1)
|
||||
jekyll-theme-architect (= 0.2.0)
|
||||
jekyll-theme-cayman (= 0.2.0)
|
||||
jekyll-theme-dinky (= 0.2.0)
|
||||
jekyll-theme-hacker (= 0.2.0)
|
||||
jekyll-theme-leap-day (= 0.2.0)
|
||||
jekyll-theme-merlot (= 0.2.0)
|
||||
jekyll-theme-midnight (= 0.2.0)
|
||||
jekyll-theme-minimal (= 0.2.0)
|
||||
jekyll-theme-modernist (= 0.2.0)
|
||||
jekyll-theme-primer (= 0.6.0)
|
||||
jekyll-theme-slate (= 0.2.0)
|
||||
jekyll-theme-tactile (= 0.2.0)
|
||||
jekyll-theme-time-machine (= 0.2.0)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.11.1)
|
||||
kramdown (= 1.17.0)
|
||||
jemoji (= 0.12.0)
|
||||
kramdown (= 2.3.1)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.3)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.10.4, < 2.0)
|
||||
rouge (= 3.13.0)
|
||||
nokogiri (>= 1.12.5, < 2.0)
|
||||
rouge (= 3.26.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.16.1)
|
||||
github-pages-health-check (1.17.9)
|
||||
addressable (~> 2.3)
|
||||
dnsruby (~> 1.60)
|
||||
octokit (~> 4.0)
|
||||
public_suffix (~> 3.0)
|
||||
public_suffix (>= 3.0, < 5.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.1)
|
||||
html-pipeline (2.14.3)
|
||||
activesupport (>= 2)
|
||||
nokogiri (>= 1.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (3.8.5)
|
||||
jekyll (3.9.0)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (~> 0.7)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (~> 1.14)
|
||||
kramdown (>= 1.17, < 3)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
|
@ -134,14 +117,16 @@ GEM
|
|||
rouge (>= 2.0, < 4.0)
|
||||
jekyll-default-layout (0.1.4)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-feed (0.13.0)
|
||||
jekyll-feed (0.15.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-gist (1.5.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.12.1)
|
||||
jekyll (~> 3.4)
|
||||
jekyll-github-metadata (2.13.0)
|
||||
jekyll (>= 3.4, < 5.0)
|
||||
octokit (~> 4.0, != 4.4.0)
|
||||
jekyll-mentions (1.5.1)
|
||||
jekyll-include-cache (0.2.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-mentions (1.6.0)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
|
@ -149,94 +134,99 @@ GEM
|
|||
jekyll-paginate (1.1.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-redirect-from (0.15.0)
|
||||
jekyll-redirect-from (0.16.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-remote-theme (0.4.1)
|
||||
jekyll-remote-theme (0.4.3)
|
||||
addressable (~> 2.0)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
rubyzip (>= 1.3.0)
|
||||
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
|
||||
rubyzip (>= 1.3.0, < 3.0)
|
||||
jekyll-sass-converter (1.5.2)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-seo-tag (2.7.1)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-sitemap (1.4.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-swiss (1.0.0)
|
||||
jekyll-theme-architect (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-architect (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-cayman (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-cayman (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-dinky (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-dinky (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-hacker (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-hacker (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-leap-day (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-leap-day (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-merlot (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-merlot (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-midnight (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-midnight (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-minimal (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-minimal (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-modernist (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-modernist (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-primer (0.5.4)
|
||||
jekyll-theme-primer (0.6.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-github-metadata (~> 2.9)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-slate (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-slate (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-tactile (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-tactile (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-time-machine (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-time-machine (0.2.0)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-titles-from-headings (0.5.3)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
jemoji (0.11.1)
|
||||
jemoji (0.12.0)
|
||||
gemoji (~> 3.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (1.17.0)
|
||||
kramdown (2.3.1)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.7.1)
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.8.1)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.15.0)
|
||||
multipart-post (2.2.0)
|
||||
nokogiri (1.12.5-x64-mingw32)
|
||||
minitest (5.18.0)
|
||||
nokogiri (1.14.3-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
octokit (4.24.0)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (3.1.1)
|
||||
racc (1.6.0)
|
||||
rb-fsevent (0.11.1)
|
||||
public_suffix (4.0.7)
|
||||
racc (1.6.2)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rouge (3.13.0)
|
||||
rexml (3.2.5)
|
||||
rouge (3.26.0)
|
||||
ruby-enum (0.9.0)
|
||||
i18n
|
||||
ruby2_keywords (0.0.5)
|
||||
|
@ -257,22 +247,19 @@ GEM
|
|||
thread_safe (0.3.6)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.9)
|
||||
tzinfo (1.2.11)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2022.1)
|
||||
tzinfo (>= 1.0.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.8.0)
|
||||
wdm (0.1.1)
|
||||
zeitwerk (2.5.4)
|
||||
zeitwerk (2.6.7)
|
||||
|
||||
PLATFORMS
|
||||
x64-mingw32
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
github-pages (~> 203)
|
||||
github-pages (~> 223)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
jekyll-feed (~> 0.12)
|
||||
minima (~> 2.5)
|
||||
|
@ -281,4 +268,4 @@ DEPENDENCIES
|
|||
wdm (~> 0.1.1)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.15
|
||||
2.4.12
|
||||
|
|
|
@ -30,8 +30,12 @@ github_username: lscharen
|
|||
|
||||
# Build settings
|
||||
theme: minima
|
||||
plugins:
|
||||
- jekyll-feed
|
||||
#plugins:
|
||||
# - jekyll-feed
|
||||
|
||||
markdown: kramdown
|
||||
highlighter: rogue
|
||||
input: GFM
|
||||
|
||||
# Exclude from processing.
|
||||
# The following items will not be processed, by default.
|
||||
|
|
|
@ -3,15 +3,4 @@ layout: page
|
|||
title: About
|
||||
---
|
||||
|
||||
This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](https://jekyllrb.com/)
|
||||
|
||||
You can find the source code for Minima at GitHub:
|
||||
[jekyll][jekyll-organization] /
|
||||
[minima](https://github.com/jekyll/minima)
|
||||
|
||||
You can find the source code for Jekyll at GitHub:
|
||||
[jekyll][jekyll-organization] /
|
||||
[jekyll](https://github.com/jekyll/jekyll)
|
||||
|
||||
|
||||
[jekyll-organization]: https://github.com/jekyll
|
||||
This is the main documentation page for the Generic Tile Engine project for the Apple IIgs.
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
---
|
||||
permalink: /getting-started
|
||||
layout: page
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
* Set Up
|
||||
* Windows
|
||||
* Linux
|
||||
* Native
|
||||
|
||||
This tutorial page will walk through the process of setting up your computer to build Apple IIgs applications
|
||||
that leverage the GTE toolset.
|
||||
## Set Up
|
||||
|
||||
### Windows
|
||||
|
||||
### Linux
|
||||
|
||||
### Native
|
||||
|
||||
If you are developing directly on an Apple IIgs machine, dowload the GTE-1.0.shk archive into your GS/OS environment. There
|
||||
are several ways of getting the file onto your system.
|
||||
|
||||
1. Use the [NetDisk](https://sheumann.github.io/NetDisk/) utility to mount to the remote disk image directly from GS/OS and copy the Tool160 file
|
||||
1. Use [ADTPro](https://adtpro.com/index.html) to transfer the disk image to the apple IIgs and write it onto a physical floppy disk
|
||||
|
||||
## Installing GTE
|
||||
|
||||
Copy the `Tool160` file into the `System:Tools` folder of your GS/OS boot volume. It is also possible to load the toolset from the application's folder (or any file system location), which will be covered later.
|
||||
|
||||
## Your First Program
|
||||
|
||||
```c
|
||||
#include <loader.h>
|
||||
#include <locator.h>
|
||||
#include <memory.h>
|
||||
#include <misctool.h>
|
||||
#include <gte.h>
|
||||
|
||||
/* create two solid tiles */
|
||||
extern Byte tiles[] = { STATIC_TILE(0x00), STATIC_TILE(0xFF) };
|
||||
|
||||
/* define a couple of key codes for the arrow keys */
|
||||
#define LEFT_ARROW 0x08
|
||||
#define RIGHT_ARROW 0x15
|
||||
#define UP_ARROW 0x0B
|
||||
#define DOWN_ARROW 0x0A
|
||||
|
||||
Word userId;
|
||||
Handle dpHandle;
|
||||
|
||||
void startUp(void) {
|
||||
TLStartUp();
|
||||
userId = MMStartUp();
|
||||
MTStartUp();
|
||||
|
||||
LoadOneTool(160, 0x0100);
|
||||
dpHandle = NewHandle(0x200L, userId, attrBank + attrPage + attrFixed + attrLocked + attrNoCross, 0);
|
||||
GTEStartUp((Word) *dpHandle, (Word) 0, userId);
|
||||
}
|
||||
|
||||
void shutDown(void) {
|
||||
GTEShutDown();
|
||||
DisposeHandle(dpHandle);
|
||||
UnloadOneTool(160);
|
||||
MTShutDown();
|
||||
MMShutDown(userId);
|
||||
TLShutDown();
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
Word keyPress;
|
||||
int x, y;
|
||||
|
||||
/* Start up GTE and its dependencies */
|
||||
startUp();
|
||||
|
||||
/* Create a 256x160 playfield (128 bytes x 160 lines) */
|
||||
GTESetScreenMode(128, 160);
|
||||
|
||||
/* Load in two tiles */
|
||||
GTELoadTileSet(0, 2, tiles);
|
||||
|
||||
/* Fill the tile store with a checkerboard pattern */
|
||||
for (y = 0; y < GTE_TILE_STORE_HEIGHT; y++) {
|
||||
for (x = 0; x < GTE_TILE_STORE_WIDTH; x++) {
|
||||
GTESetTile(x, y, (x + y) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enter into the main loop */
|
||||
x = y = 0;
|
||||
do {
|
||||
keyPress = GTEReadControl() & PAD_KEY_CODE;
|
||||
|
||||
if (keyPress == LEFT_ARROW && x > 0) x--;
|
||||
if (keyPress == RIGHT_ARROW && x < 1000) x++;
|
||||
if (keyPress == UP_ARROW && y > 0) y--;
|
||||
if (keyPress == DOWN_ARROW && y < 1000) y++;
|
||||
|
||||
/* Position the screen and render */
|
||||
GTESetBG0Origin(x, y);
|
||||
GTERender(0);
|
||||
}
|
||||
while (keyPress != 'Q' && keyPress != 'q');
|
||||
|
||||
shutDown();
|
||||
}
|
||||
```
|
|
@ -4,3 +4,5 @@
|
|||
|
||||
layout: home
|
||||
---
|
||||
|
||||
* [Getting Started]({{ site.baseurl }}/getting-started.html)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
layout: page
|
||||
---
|
||||
|
||||
<script>
|
||||
var emulator = new Emulator(document.querySelector("#canvas"),
|
||||
null,
|
||||
new MAMELoader(MAMELoader.driver("1943"),
|
||||
MAMELoader.nativeResolution(224, 256),
|
||||
MAMELoader.scale(3),
|
||||
MAMELoader.emulatorJS("emulators/mess1943.js"),
|
||||
MAMELoader.mountFile("1943.zip",
|
||||
MAMELoader.fetchFile("Game File",
|
||||
"examples/1943.zip"))))
|
||||
emulator.start({ waitAfterDownloading: true });
|
||||
</script>
|
||||
<canvas id="canvas" width="800" height="600"></canvas>
|
|
@ -0,0 +1,118 @@
|
|||
---
|
||||
layout: page
|
||||
style: sample
|
||||
---
|
||||
|
||||
```c
|
||||
#include <loader.h>
|
||||
#include <locator.h>
|
||||
#include <memory.h>
|
||||
#include <misctool.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "gte.h"
|
||||
#include "demo_data.h"
|
||||
|
||||
#define TOOLFAIL(string) if (toolerror()) SysFailMgr(toolerror(), "\p" string "\n\r Error Code -> $");
|
||||
|
||||
#define SPRITE_START_TILE 2
|
||||
#define SPRITE_SLOT 0
|
||||
#define SPRITE_VBUFF (GTE_VBUFF_SPRITE_START+0*GTE_VBUFF_SPRITE_STEP)
|
||||
|
||||
int main (void) {
|
||||
Word controlMask;
|
||||
Word keyPress;
|
||||
Word userId;
|
||||
Handle dpHndl;
|
||||
Word dpWord;
|
||||
Word x = 0, y = 0;
|
||||
Word px = 0, py = 0;
|
||||
Word sec;
|
||||
|
||||
TLStartUp();
|
||||
TOOLFAIL("Unable to start tool locator");
|
||||
|
||||
userId = MMStartUp();
|
||||
TOOLFAIL("Unable to start memory manager");
|
||||
|
||||
MTStartUp();
|
||||
TOOLFAIL("Unable to start misc tools");
|
||||
|
||||
LoadGTEToolSet(userId);
|
||||
|
||||
dpHndl = NewHandle(0x0200, userId, 0x4015, 0);
|
||||
if (dpHndl == NULL) {
|
||||
TOOLFAIL("Unable to allocate page 0 memory");
|
||||
}
|
||||
dpWord = (Word)(*dpHndl);
|
||||
if ((dpWord & 0x00FF) != 0x0000) {
|
||||
TOOLFAIL("Allocated page 0 memory is not aligned");
|
||||
}
|
||||
|
||||
GTEStartUp(dpWord, 0x0000, userId);
|
||||
TOOLFAIL("Unable to start GTE");
|
||||
|
||||
GTESetScreenMode(160, 200);
|
||||
GTELoadTileSet(tiles);
|
||||
GTESetPalette(0, (Pointer)palette);
|
||||
GTEFillTileStore(1);
|
||||
|
||||
GTECreateSpriteStamp(GTE_SPRITE_8X8 | SPRITE_START_TILE, SPRITE_VBUFF);
|
||||
GTEAddSprite(SPRITE_SLOT, 0, SPRITE_VBUFF, px, py);
|
||||
|
||||
do {
|
||||
controlMask = GTEReadControl();
|
||||
keyPress = controlMask & 0x007F;
|
||||
|
||||
switch (keyPress) {
|
||||
case ' ': // Toggle background
|
||||
sec = GTEGetSeconds();
|
||||
GTEFillTileStore(1 + (sec & 1));
|
||||
break;
|
||||
|
||||
case 'a': if (x > 0) { x--; }
|
||||
break;
|
||||
|
||||
case 'd': if (x < 1000) { x++; }
|
||||
break;
|
||||
|
||||
case 'w': if (y > 0) { y--; }
|
||||
break;
|
||||
|
||||
case 's': if (y < 1000) { y++; }
|
||||
break;
|
||||
|
||||
|
||||
case 'j': if (px > 0) { px--; }
|
||||
break;
|
||||
|
||||
case 'l': if (px < 154) { px++; }
|
||||
break;
|
||||
|
||||
case 'i': if (py > 0) { py--; }
|
||||
break;
|
||||
|
||||
case 'k': if (py < 192) { py++; }
|
||||
break;
|
||||
}
|
||||
|
||||
GTESetBG0Origin(x, y);
|
||||
GTEMoveSprite(SPRITE_SLOT, px, py);
|
||||
GTERender(0);
|
||||
|
||||
} while (keyPress != 'q' && keyPress != 'Q');
|
||||
|
||||
GTEShutDown();
|
||||
|
||||
DisposeHandle(dpHndl);
|
||||
|
||||
MTShutDown();
|
||||
TOOLFAIL("Unable to shutdown misc tool");
|
||||
|
||||
MMShutDown(userId);
|
||||
TOOLFAIL("Unable to shutdown memory manager");
|
||||
|
||||
TLShutDown();
|
||||
TOOLFAIL("Unable to shutdown tool locator");
|
||||
}
|
||||
```
|
|
@ -89,7 +89,11 @@ style: toolref
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="#GTECreateSpriteStamp">GTECreateSpriteStamp</a></td>
|
||||
<td> Creates a sprite stamp from the tile set</td>
|
||||
<td>Creates a sprite stamp from the tile set</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#GTECompileSpriteStamp">GTECompileSpriteStamp</a></td>
|
||||
<td>Created a compiled sprite from a sprite stamp</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#GTEAddSprite">GTEAddSprite</a></td>
|
||||
|
@ -794,12 +798,12 @@ style: toolref
|
|||
<tr>
|
||||
<td class="bot">width</td>
|
||||
<td><em></em></td>
|
||||
<td><em>Word</em>—Width of the playfield in pixels. Must be even.</td>
|
||||
<td><em>Word</em>—Width of the playfield in bytes. Must be even.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">height</td>
|
||||
<td><em></em></td>
|
||||
<td><em>Word</em>—Height of the playfield in pixels.</td>
|
||||
<td><em>Word</em>—Height of the playfield in scanlines.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot"></td>
|
||||
|
@ -1207,10 +1211,25 @@ style: toolref
|
|||
<td>Offsets each column of the secondary background's vertical position. Unimplemented.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RENDER_BG1_ROTATIONT</td>
|
||||
<td>$0004</td>
|
||||
<td>RENDER_BG1_ROTATION</td>
|
||||
<td>$0008</td>
|
||||
<td>Use the internal rotation tables to render the secondary background</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RENDER_PER_SCANLINE</td>
|
||||
<td>$0010</td>
|
||||
<td>Set individual scanline properties for the primary and secondary backgrounds from a table.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RENDER_WITH_SHADOWING</td>
|
||||
<td>$0020</td>
|
||||
<td>Uses a rendering mode that does not draw sprites into the tiles but uses shadowing to draw sprites on top of the rendered background and then expose the final composited image. This mode is required to use compiled sprites.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RENDER_SPRITES_SORTED</td>
|
||||
<td>$0040</td>
|
||||
<td>Draws the sprite in y-sorted order instead of sprite slot order.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -1234,9 +1253,18 @@ style: toolref
|
|||
</p>
|
||||
<p>
|
||||
A tile set is an array of (up to) 512 tile definitions and each tile definition is 128 bytes. The tile definition
|
||||
is comprised of four, 32-byte tiles; a normal tile, its mask, a horizontally flipped versio of the tile and its mask.
|
||||
is comprised of four, 32-byte tiles; a normal tile, its mask, a horizontally flipped version of the tile and its mask.
|
||||
The first 128 bytes of a tileset must be set to zero.
|
||||
</p>
|
||||
<p>
|
||||
The <em>start</em> and <em>finish</em> parameters define a subset of tiles to be copied into the GTE memory
|
||||
buffer. This is most commonly used to load a small number of tiles to avoid needing to store a full set of 512
|
||||
tiles that are mostly unushed. For eample, loading in 16 tiles can be performed as <tt>GTELoadTileSet(0, 17, tilePtr)</tt>.
|
||||
</p>
|
||||
<p>
|
||||
This function can also be used to swap out subsets of tiles on the fly. Any tiles that are replaced which may
|
||||
be on-screen are not automatically refreshed.
|
||||
</p>
|
||||
<div class="section">
|
||||
<h5>Parameters</h5>
|
||||
<table class="stack">
|
||||
|
@ -1252,6 +1280,16 @@ style: toolref
|
|||
<tr>
|
||||
<td class="top">previous contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">start</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—index of the first tile to copy</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">finish</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—terminating index. This tile is not copied.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">tileSetPtr</td>
|
||||
<td></td>
|
||||
|
@ -1292,7 +1330,9 @@ style: toolref
|
|||
</div>
|
||||
<div class="section">
|
||||
<h5>C</h5>
|
||||
<p><tt>extern pascal void GTELoadTileSet(tileSetPtr)</tt></p>
|
||||
<p><tt>extern pascal void GTELoadTileSet(start, finish, tileSetPtr)</tt></p>
|
||||
<p><tt>Word start;</tt></p>
|
||||
<p><tt>Word finish;</tt></p>
|
||||
<p><tt>Pointer tileSetPtr;</tt></p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1322,9 +1362,9 @@ style: toolref
|
|||
<td class="top">previous contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">spriteID</td>
|
||||
<td class="bot">spriteIdent</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—sprite descriptor word</td>
|
||||
<td><em>Word</em>—sprite identifier word</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">vBuffAddr</td>
|
||||
|
@ -1366,14 +1406,14 @@ style: toolref
|
|||
</div>
|
||||
<div class="section">
|
||||
<h5>C</h5>
|
||||
<p><tt>extern pascal void GTECreateSpriteStamp(spriteID, vBuffAddr)</tt></p>
|
||||
<p><tt>Word spriteID;</tt></p>
|
||||
<p><tt>extern pascal void GTECreateSpriteStamp(spriteIdent, vBuffAddr)</tt></p>
|
||||
<p><tt>Word spriteIdent;</tt></p>
|
||||
<p><tt>Word vBuffAddr;</tt></p>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h5>Sprite Descriptor</h5>
|
||||
<h5>Sprite Identifier</h5>
|
||||
<p>
|
||||
The sprite descriptor is a subset of the full sprite bitfield. Only the starting Tile Index and
|
||||
The sprite identifier is a subset of the full sprite descriptor. Only the starting Tile Index and
|
||||
the size bits are used.
|
||||
</p>
|
||||
<p>
|
||||
|
@ -1403,6 +1443,90 @@ style: toolref
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="api">
|
||||
<h4 class="tn">$2DXX</h4>
|
||||
<h4 id="GTECompileSpriteStamp">GTECompileSpriteStamp</h4>
|
||||
<p>
|
||||
Creates a compiled sprite in a special compilation buffer from an existing sprite stamp. The return value
|
||||
is an address token that can be passed into the AddSprite function in place of the vBuffAddr parameter as
|
||||
long as the `SPRITE_COMPILED` flag is set.
|
||||
</p>
|
||||
<div class="section">
|
||||
<h5>Parameters</h5>
|
||||
<table class="stack">
|
||||
<colgroup>
|
||||
<col class="col-1">
|
||||
<col class="col-2">
|
||||
<col class="col-3">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Stack before call</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="top">previous contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">wordspace</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Space for result</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">spriteIdent</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—sprite identifier word</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">vBuffAddr</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Location in the sprite vitual buffer.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot"></td>
|
||||
<td><em>←</em></td>
|
||||
<td><em>SP</em></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="stack">
|
||||
<colgroup>
|
||||
<col class="col-1">
|
||||
<col class="col-2">
|
||||
<col class="col-3">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Stack after call</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="top">previous contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">addr</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Location in the sprite compilation buffer.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot"></td>
|
||||
<td><em>←</em></td>
|
||||
<td><em>SP</em></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h5>Errors</h5>
|
||||
<p>None</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h5>C</h5>
|
||||
<p><tt>extern pascal Word GTECompileSpriteStamp(spriteIdent, vBuffAddr)</tt></p>
|
||||
<p><tt>Word spriteIdent;</tt></p>
|
||||
<p><tt>Word vBuffAddr;</tt></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="api">
|
||||
<h4 class="tn">$10XX</h4>
|
||||
<h4 id="GTEAddSprite">GTEAddSprite</h4>
|
||||
|
@ -1432,7 +1556,17 @@ style: toolref
|
|||
<tr>
|
||||
<td class="bot">spriteSlot</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Sprite slot assigned to this new sprite.</td>
|
||||
<td><em>Word</em>—The slot to assign the sprite to. There are 16 slots and sprites in lower slots are drawn above the sprites in higher slots.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">spriteFlags</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Sprite flags that define the sprite's properties.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">vBuffAddr</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Sprite address in the VBUFF space, or a compiled sprite address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">x</td>
|
||||
|
@ -1444,11 +1578,6 @@ style: toolref
|
|||
<td></td>
|
||||
<td><em>Word</em>—Signed vertical sprite position on the playfield.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">vBuffAddr</td>
|
||||
<td></td>
|
||||
<td><em>Word</em>—Address of the stamp to use for this sprite. A stamp can be shared by multiple sprites.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot"></td>
|
||||
<td><em>←</em></td>
|
||||
|
@ -1484,11 +1613,12 @@ style: toolref
|
|||
</div>
|
||||
<div class="section">
|
||||
<h5>C</h5>
|
||||
<p><tt>extern pascal void GTEAddSprite(spriteSlot, x, y, vBuffAddr)</tt></p>
|
||||
<p><tt>extern pascal void GTEAddSprite(spriteSlot, spriteFlags, vBuffAddr, x, y)</tt></p>
|
||||
<p><tt>Word spriteSlot;</tt></p>
|
||||
<p><tt>Word spriteDescriptor;</tt></p>
|
||||
<p><tt>Word vBuffAddr;</tt></p>
|
||||
<p><tt>Word x;</tt></p>
|
||||
<p><tt>Word y;</tt></p>
|
||||
<p><tt>Word vBuffAddr;</tt></p>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h5>Sprite Descriptor</h5>
|
||||
|
@ -3023,7 +3153,7 @@ style: toolref
|
|||
<div class="api">
|
||||
<h4 class="tn">$24XX</h4>
|
||||
<h4 id="GTEGetTileDataAddr">GTEGetTileDataAddr</h4>
|
||||
<p>This API is under active development at this time.</p>
|
||||
<p>Returns a pointer to the bottom of the internal tile data memory. The data for each tile can be found at offset <tt>N * 128</tt></p>
|
||||
<div class="section">
|
||||
<h5>Parameters</h5>
|
||||
<table class="stack">
|
||||
|
@ -3039,6 +3169,11 @@ style: toolref
|
|||
<tr>
|
||||
<td class="top">previous contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">longspace</td>
|
||||
<td></td>
|
||||
<td><em>Long</em>—Space for result</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot"></td>
|
||||
<td><em>←</em></td>
|
||||
|
@ -3060,6 +3195,11 @@ style: toolref
|
|||
<tr>
|
||||
<td class="top">previous contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot">tileDataPtr</td>
|
||||
<td></td>
|
||||
<td><em>Long</em>—<span class="sc">pointer</span> to the tile data</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="bot"></td>
|
||||
<td><em>←</em></td>
|
||||
|
@ -3074,6 +3214,7 @@ style: toolref
|
|||
</div>
|
||||
<div class="section">
|
||||
<h5>C</h5>
|
||||
<p><tt>extern pascal Pointer GTEGetTileDataAddr()</tt></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
layout: page
|
||||
title: Examples
|
||||
---
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
****************************************
|
||||
_Err mac
|
||||
bcc NoErr
|
||||
do ]0 ; (DO if true)
|
||||
do ]0 ; (DO if true) Mu
|
||||
jsr PgmDeath ; this is conditionally compiled if
|
||||
str ]1 ; we pass in an error statement
|
||||
else ; (ELSE)
|
||||
|
@ -93,6 +93,16 @@ _PullReg2 mac
|
|||
pla
|
||||
<<<
|
||||
|
||||
phxy mac
|
||||
phx
|
||||
phy
|
||||
<<<
|
||||
|
||||
plyx mac
|
||||
ply
|
||||
plx
|
||||
<<<
|
||||
|
||||
jne mac
|
||||
beq *+5
|
||||
jmp ]1
|
||||
|
@ -103,6 +113,16 @@ jeq mac
|
|||
jmp ]1
|
||||
<<<
|
||||
|
||||
jmi mac
|
||||
bpl *+5
|
||||
jmp ]1
|
||||
<<<
|
||||
|
||||
jpl mac
|
||||
bmi *+5
|
||||
jmp ]1
|
||||
<<<
|
||||
|
||||
jcc mac
|
||||
bcs *+5
|
||||
jmp ]1
|
||||
|
@ -113,6 +133,12 @@ jcs mac
|
|||
jmp ]1
|
||||
<<<
|
||||
|
||||
max mac
|
||||
cmp ]1
|
||||
bcs mout
|
||||
lda ]1
|
||||
mout <<<
|
||||
|
||||
min mac
|
||||
cmp ]1
|
||||
bcc mout
|
||||
|
@ -166,216 +192,3 @@ ScriptStep MAC
|
|||
dw ]1,]2,]3,]4
|
||||
FIN
|
||||
<<<
|
||||
|
||||
; A specialized CopyMaskedWord macro that draws a tile from a direct page workspace. Used
|
||||
; to render fringe tiles and sprite tiles when BG1 is active. If there is no second background,
|
||||
; then one should use the optimized functions which assumes a PEA opcode and only
|
||||
; needs to copy data words
|
||||
;
|
||||
; ]1 : tiledata direct page address , the tilemask direct page address is tiledata + 32
|
||||
; ]2 : code field offset
|
||||
CopyMaskedWordD MAC
|
||||
lda ]1+32 ; load the mask value
|
||||
bne mixed ; a non-zero value may be mixed
|
||||
|
||||
; This is a solid word
|
||||
lda #$00F4 ; PEA instruction
|
||||
sta: ]2,y
|
||||
lda ]1 ; load the tile data
|
||||
sta: ]2+1,y ; PEA operand
|
||||
bra next
|
||||
|
||||
mixed cmp #$FFFF ; All 1's in the mask is fully transparent
|
||||
beq transparent
|
||||
|
||||
; This is the slowest path because there is a *lot* of work to do. So much that it's
|
||||
; worth it to change up the environment to optimize things a bit more.
|
||||
;
|
||||
; Need to fill in the first 10 bytes of the JMP handler with the following code sequence
|
||||
;
|
||||
; lda (00),y
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
|
||||
lda #$004C ; JMP instruction
|
||||
sta: ]2,y
|
||||
|
||||
ldx _X_REG ; Get the addressing offset
|
||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
adc #{]2&$F000} ; adjust for the current row offset
|
||||
sta: ]2+1,y
|
||||
|
||||
tay ; This becomes the new address that we use to patch in
|
||||
txa ; Get the offset and render a LDA (dp),y instruction
|
||||
|
||||
sep #$20
|
||||
sta: $0001,y ; LDA (00),y operand
|
||||
lda #$B1
|
||||
sta: $0000,y ; LDA (00),y opcode
|
||||
lda #$29
|
||||
sta: $0002,y ; AND #$0000 opcode
|
||||
lda #$09
|
||||
sta: $0005,y ; ORA #$0000 opcode
|
||||
rep #$20
|
||||
|
||||
lda ]1+32 ; insert the tile mask and data into the exception
|
||||
sta: $0003,y ; handler.
|
||||
lda ]1
|
||||
sta: $0006,y
|
||||
|
||||
lda #$0D80 ; branch to the prologue (BRA *+15)
|
||||
sta: $0008,y
|
||||
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the second background layer
|
||||
transparent
|
||||
lda #$00B1 ; LDA (dp),y instruction
|
||||
sta: ]2,y
|
||||
lda _X_REG ; X is the logical tile offset (0, 2, 4, ... 82) left-to-right
|
||||
ora #$4800 ; put a PHA after the offset
|
||||
sta: ]2+1,y
|
||||
next
|
||||
eom
|
||||
|
||||
; Macros to use in the Masked Tile renderer
|
||||
;
|
||||
; ]1 : tiledata offset
|
||||
; ]2 : tilemask offset
|
||||
; ]3 : code field offset
|
||||
CopyMaskedWord MAC
|
||||
ldal ]2,x ; load the mask value
|
||||
bne mixed ; a non-zero value may be mixed
|
||||
|
||||
; This is a solid word
|
||||
lda #$00F4 ; PEA instruction
|
||||
sta: ]3,y
|
||||
ldal ]1,x ; load the tile data
|
||||
sta: ]3+1,y ; PEA operand
|
||||
bra next
|
||||
|
||||
mixed cmp #$FFFF ; All 1's in the mask is fully transparent
|
||||
beq transparent
|
||||
|
||||
; This is the slowest path because there is a *lot* of work to do. So much that it's
|
||||
; worth it to change up the environment to optimize things a bit more.
|
||||
;
|
||||
; Need to fill in the first 8 bytes of the JMP handler with the following code sequence
|
||||
;
|
||||
; lda (00),y
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
|
||||
lda #$004C ; JMP instruction
|
||||
sta: ]3,y
|
||||
|
||||
ldx _X_REG ; Get the addressing offset
|
||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
||||
ora _BASE_ADDR ; of the current code field row (2 rows per bank) $0000 or $8000
|
||||
ora #{]3&$7000} ; adjust for the current line offset within the row
|
||||
sta: ]3+1,y
|
||||
|
||||
tay ; This becomes the new address that we use to patch in
|
||||
txa ; Get the offset and render a LDA (dp),y instruction
|
||||
|
||||
sep #$20
|
||||
sta: $0001,y ; LDA (00),y operand
|
||||
lda #$B1
|
||||
sta: $0000,y ; LDA (00),y opcode
|
||||
lda #$29
|
||||
sta: $0002,y ; AND #$0000 opcode
|
||||
lda #$09
|
||||
sta: $0005,y ; ORA #$0000 opcode
|
||||
rep #$20
|
||||
|
||||
ldx _T_PTR ; restore the original x-register value
|
||||
ldal ]2,x ; insert the tile mask and data into the exception
|
||||
sta: $0003,y ; handler.
|
||||
ldal ]1,x
|
||||
sta: $0006,y
|
||||
|
||||
; Copy the top 9 bytes down. We have 23 bytes of space and are only using 8. Since 9 + 8 = 17 < 23, we
|
||||
; can save 3 cycles per word by eliminating the BRA instruction
|
||||
|
||||
; lda #$0D80 ; branch to the prologue (BRA *+15)
|
||||
; sta: $0008,y
|
||||
|
||||
lda: $0017,y
|
||||
sta: $0008,y
|
||||
lda: $0019,y
|
||||
sta: $000A,y
|
||||
lda: $001B,y
|
||||
sta: $000C,y
|
||||
lda: $001D,y
|
||||
sta: $000E,y
|
||||
lda: $001E,y
|
||||
sta: $000F,y
|
||||
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the second background layer
|
||||
transparent
|
||||
lda #$00B1 ; LDA (dp),y instruction
|
||||
sta: ]3,y
|
||||
lda _X_REG ; X is the logical tile offset (0, 2, 4, ... 82) left-to-right
|
||||
ora #$4800 ; put a PHA after the offset
|
||||
sta: ]3+1,y
|
||||
next
|
||||
eom
|
||||
|
||||
; Large code blocks that can be used in sprite blitters
|
||||
; ]1: line number
|
||||
OneSpriteToCodeField mac
|
||||
lda blttmp+{]1*4}
|
||||
andl spritemask+{]1*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]1*SPRITE_PLANE_SPAN},x
|
||||
sta: $0004+{]1*$1000},y
|
||||
|
||||
lda blttmp+{]1*4}+2
|
||||
andl spritemask+{]1*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]1*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: $0001+{]1*$1000},y
|
||||
eom
|
||||
|
||||
TwoSpritesToCodeField mac
|
||||
ldy #{]1*SPRITE_PLANE_SPAN}
|
||||
lda blttmp+{]1*4}
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0004+{]1*$1000},x
|
||||
|
||||
ldy #{]1*SPRITE_PLANE_SPAN}+2
|
||||
lda blttmp+{]1*4}+2
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0001+{]1*$1000},x
|
||||
eom
|
||||
|
||||
ThreeSpritesToCodeField mac
|
||||
ldy #{]1*SPRITE_PLANE_SPAN}
|
||||
lda blttmp+{]1*4}
|
||||
andl [spritemask_2],y
|
||||
oral [spritedata_2],y
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0004+{]1*$1000},x
|
||||
|
||||
ldy #{]1*SPRITE_PLANE_SPAN}+2
|
||||
lda blttmp+{]1*4}+2
|
||||
andl [spritemask_2],y
|
||||
oral [spritedata_2],y
|
||||
andl [spritemask_1],y
|
||||
oral [spritedata_1],y
|
||||
andl [spritemask_0],y
|
||||
oral [spritedata_0],y
|
||||
sta: $0001+{]1*$1000},x
|
||||
eom
|
||||
|
|
|
@ -126,6 +126,18 @@ _GTEClearBG1Buffer MAC
|
|||
_GTESetBG1Scale MAC
|
||||
UserTool $2B00+GTEToolNum
|
||||
<<<
|
||||
_GTEGetAddress MAC
|
||||
UserTool $2C00+GTEToolNum
|
||||
<<<
|
||||
_GTECompileSpriteStamp MAC
|
||||
UserTool $2D00+GTEToolNum
|
||||
<<<
|
||||
_GTESetAddress MAC
|
||||
UserTool $2E00+GTEToolNum
|
||||
<<<
|
||||
_GTEUpdateOverlay MAC
|
||||
UserTool $2F00+GTEToolNum
|
||||
<<<
|
||||
|
||||
; EngineMode definitions
|
||||
; Script definition
|
||||
|
@ -146,17 +158,37 @@ PAD_KEY_DOWN equ $0400
|
|||
ENGINE_MODE_TWO_LAYER equ $0001
|
||||
ENGINE_MODE_DYN_TILES equ $0002
|
||||
ENGINE_MODE_BNK0_BUFF equ $0004
|
||||
ENGINE_MODE_USER_TOOL equ $8000 ; Communicate if GTE is loaded as a system tool, or a user tool
|
||||
|
||||
; Render flags
|
||||
RENDER_ALT_BG1 equ $0001
|
||||
RENDER_BG1_HORZ_OFFSET equ $0002
|
||||
RENDER_BG1_VERT_OFFSET equ $0004
|
||||
RENDER_BG1_ROTATION equ $0008
|
||||
RENDER_PER_SCANLINE equ $0010
|
||||
RENDER_WITH_SHADOWING equ $0020
|
||||
RENDER_SPRITES_SORTED equ $0040
|
||||
|
||||
; Overlay flags
|
||||
OVERLAY_MASKED equ $0000 ; Overlay has a mask, so the background must be draw first
|
||||
OVERLAY_SOLID equ $8000 ; Overlay covers the scan line and is fully opaque
|
||||
OVERLAY_ABOVE equ $0000 ; Overlay is drawn above scanline sprites
|
||||
OVERLAY_BELOW equ $4000 ; Overlay is drawn below scanline sprites
|
||||
|
||||
; GetAddress IDs
|
||||
scanlineHorzOffset equ $0001
|
||||
scanlineHorzOffset2 equ $0002
|
||||
tileStore equ $0003
|
||||
vblCallback equ $0004
|
||||
|
||||
; CopyPicToBG1 flags
|
||||
COPY_PIC_NORMAL equ $0000 ; Copy into BG1 buffer in "normal mode"
|
||||
COPY_PIC_SCANLINE equ $0001 ; Copy in a way to support BG1 + RENDER_PER_SCANLINE.
|
||||
|
||||
; Tile constants
|
||||
; TILE_RESERVED_BIT equ $8000
|
||||
TILE_PRIORITY_BIT equ $4000 ; Put tile on top of sprite
|
||||
TILE_FRINGE_BIT equ $2000 ; Unused
|
||||
TILE_USER_BIT equ $2000 ; User-defined tile. Execute registered callback.
|
||||
TILE_SOLID_BIT equ $1000 ; Hint bit used in TWO_LAYER_MODE to optimize rendering
|
||||
TILE_DYN_BIT equ $0800 ; Is this a Dynamic Tile?
|
||||
TILE_VFLIP_BIT equ $0400
|
||||
|
@ -164,8 +196,8 @@ TILE_HFLIP_BIT equ $0200
|
|||
TILE_ID_MASK equ $01FF
|
||||
TILE_CTRL_MASK equ $FE00
|
||||
|
||||
|
||||
; Sprite constants
|
||||
SPRITE_COMPILED equ $4000 ; This is a compiled sprite
|
||||
SPRITE_HIDE equ $2000
|
||||
SPRITE_16X16 equ $1800
|
||||
SPRITE_16X8 equ $1000
|
||||
|
|
|
@ -1,8 +1,192 @@
|
|||
{
|
||||
"name": "generic-tile-engine",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "generic-tile-engine",
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"pngjs": "^6.0.0",
|
||||
"string-builder": "^0.1.8",
|
||||
"watch": "latest",
|
||||
"xml2json": "^0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/exec-sh": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz",
|
||||
"integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"merge": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/hoek": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
|
||||
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
|
||||
"deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/isemail": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz",
|
||||
"integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"punycode": "2.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/joi": {
|
||||
"version": "13.7.0",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz",
|
||||
"integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==",
|
||||
"deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"hoek": "5.x.x",
|
||||
"isemail": "3.x.x",
|
||||
"topo": "3.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/joi/node_modules/hoek": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz",
|
||||
"integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==",
|
||||
"deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/merge": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
|
||||
"integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nan": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
|
||||
"integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-expat": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.4.0.tgz",
|
||||
"integrity": "sha512-X8Y/Zk/izfNgfayeOeUGqze7KlaOwVJ9SDTjHUMKd0hu0aFTRpLlLCBwmx79cTPiQWD24I1YOafF+U+rTvEMfQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"nan": "^2.13.2"
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
|
||||
"integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/string-builder": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/string-builder/-/string-builder-0.1.8.tgz",
|
||||
"integrity": "sha512-0pUtikmhChLaf+uLqzYTgzTCQc4jAjaWHolxPGq3D77SgSoTqkOlv0RVF3XwDxMR9x/y1WPPwkTNalZCA9DGnQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/topo": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz",
|
||||
"integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==",
|
||||
"deprecated": "This module has moved and is now available at @hapi/topo. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"hoek": "6.x.x"
|
||||
}
|
||||
},
|
||||
"node_modules/topo/node_modules/hoek": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz",
|
||||
"integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==",
|
||||
"deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/watch": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz",
|
||||
"integrity": "sha512-1u+Z5n9Jc1E2c7qDO8SinPoZuHj7FgbgU1olSFoyaklduDvvtX7GMMtlE6OC9FTXq4KvNAOfj6Zu4vI1e9bAKA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"exec-sh": "^0.2.0",
|
||||
"minimist": "^1.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"watch": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.1.95"
|
||||
}
|
||||
},
|
||||
"node_modules/xml2json": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2json/-/xml2json-0.12.0.tgz",
|
||||
"integrity": "sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"hoek": "^4.2.1",
|
||||
"joi": "^13.1.2",
|
||||
"node-expat": "^2.3.18"
|
||||
},
|
||||
"bin": {
|
||||
"xml2json": "bin/xml2json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.5.0",
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
"crossrunner": "C:\\Programs\\Crossrunner\\Crossrunner.exe"
|
||||
},
|
||||
"scripts": {
|
||||
"gsport": "%npm_package_config_gsport%",
|
||||
"build:image": "npm run build && build-image.bat %npm_package_config_cadius%",
|
||||
"build:docs": "cd docs && bundle exec jekyll serve",
|
||||
"archive": "%npm_package_config_cadius% EXTRACTFILE ./emu/Target.2mg /GTEDev/Tool160.SHK .",
|
||||
"test": "npm run build && build-image.bat %npm_package_config_cadius% && %npm_package_config_gsport%",
|
||||
|
|
126
src/Core.s
126
src/Core.s
|
@ -1,126 +0,0 @@
|
|||
use Util.Macs.s
|
||||
use Load.Macs.s
|
||||
use Locator.Macs.s
|
||||
use Mem.Macs.s
|
||||
use Misc.Macs.s
|
||||
use Tool222.MACS.s
|
||||
use Core.MACS.s
|
||||
|
||||
use .\Defs.s
|
||||
|
||||
EngineStartUp ENT
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
|
||||
jsr ToolStartUp ; Start up the toolbox tools we rely on
|
||||
jsr _CoreStartUp
|
||||
jsr SoundStartUp ; Start up any sound/music tools
|
||||
|
||||
plb
|
||||
rtl
|
||||
|
||||
EngineShutDown ENT
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
|
||||
jsr SoundShutDown
|
||||
jsr _CoreShutDown
|
||||
jsr ToolShutDown
|
||||
|
||||
plb
|
||||
rtl
|
||||
|
||||
ToolStartUp
|
||||
_TLStartUp ; normal tool initialization
|
||||
pha
|
||||
_MMStartUp
|
||||
_Err ; should never happen
|
||||
pla
|
||||
sta MasterId ; our master handle references the memory allocated to us
|
||||
ora #$0100 ; set auxID = $01 (valid values $01-0f)
|
||||
sta UserId ; any memory we request must use our own id
|
||||
|
||||
_MTStartUp
|
||||
rts
|
||||
|
||||
MasterId ds 2
|
||||
|
||||
; Fatal error handler invoked by the _Err macro
|
||||
PgmDeath tax
|
||||
pla
|
||||
inc
|
||||
phx
|
||||
phk
|
||||
pha
|
||||
bra ContDeath
|
||||
PgmDeath0 pha
|
||||
pea $0000
|
||||
pea $0000
|
||||
ContDeath ldx #$1503
|
||||
jsl $E10000
|
||||
|
||||
; Use Tool222 (NinjaTrackerPlus) for music playback
|
||||
SoundStartUp
|
||||
lda #NO_MUSIC
|
||||
bne :no_music
|
||||
|
||||
pea $00DE
|
||||
pea $0000
|
||||
_LoadOneTool
|
||||
_Err
|
||||
|
||||
lda UserId
|
||||
pha
|
||||
_NTPStartUp
|
||||
:no_music
|
||||
rts
|
||||
|
||||
SoundShutDown
|
||||
lda #NO_MUSIC
|
||||
bne :no_music
|
||||
_NTPShutDown
|
||||
:no_music
|
||||
rts
|
||||
|
||||
ToolShutDown
|
||||
rts
|
||||
|
||||
put CoreImpl.s
|
||||
put blitter/Template.s
|
||||
|
||||
put Memory.s
|
||||
put Graphics.s
|
||||
put Sprite.s
|
||||
put blitter/Tiles.s
|
||||
put Sprite2.s
|
||||
put SpriteRender.s
|
||||
put Render.s
|
||||
put Timer.s
|
||||
put Script.s
|
||||
put blitter/Blitter.s
|
||||
put blitter/Horz.s
|
||||
put blitter/PEISlammer.s
|
||||
put blitter/Tables.s
|
||||
put blitter/Tiles00000.s ; normal tiles
|
||||
put blitter/Tiles00001.s ; dynamic tiles
|
||||
put blitter/Tiles00010.s ; normal masked tiles
|
||||
put blitter/Tiles00011.s ; dynamic masked tiles
|
||||
|
||||
put blitter/Tiles10000.s ; normal tiles + sprites
|
||||
put blitter/Tiles10001.s ; dynamic tiles + sprites
|
||||
put blitter/Tiles10010.s ; normal masked tiles + sprites
|
||||
put blitter/Tiles10011.s ; dynamic masked tiles + sprites
|
||||
|
||||
put blitter/Tiles11000.s ; normal high priority tiles + sprites
|
||||
put blitter/Tiles11001.s ; dynamic high priority tiles + sprites
|
||||
put blitter/Tiles11010.s ; normal high priority masked tiles + sprites
|
||||
put blitter/Tiles11011.s ; dynamic high priority masked tiles + sprites
|
||||
|
||||
put blitter/TilesBG1.s
|
||||
put blitter/Vert.s
|
||||
put blitter/BG0.s
|
||||
put blitter/BG1.s
|
||||
put blitter/SCB.s
|
||||
put TileMap.s
|
|
@ -166,8 +166,14 @@ OneSecHandler mx %11
|
|||
|
||||
; This is OK, it's referenced by a long address
|
||||
VBLTASK hex 00000000
|
||||
dw 0
|
||||
TaskCnt dw 1
|
||||
hex 5AA5
|
||||
VblTaskCode mx %11
|
||||
lda #1
|
||||
stal TaskCnt ; Reset the task count
|
||||
_VblTaskPatch jml _TaskStub ; Just something to catch the interrupt
|
||||
_TaskStub rtl
|
||||
mx %00
|
||||
|
||||
; Reset the engine to a known state
|
||||
; Blitter initialization
|
||||
|
@ -220,6 +226,8 @@ EngineReset
|
|||
stz BG1TileMapPtr
|
||||
stz BG1TileMapPtr+2
|
||||
|
||||
stz CompileBankTop
|
||||
|
||||
stz SCBArrayPtr
|
||||
stz SCBArrayPtr+2
|
||||
|
||||
|
@ -233,6 +241,7 @@ EngineReset
|
|||
sta tmp15
|
||||
stz tmp14
|
||||
|
||||
; Rebuild all of the bank blitters
|
||||
:loop
|
||||
ldx #BlitBuff
|
||||
lda #^BlitBuff
|
||||
|
@ -247,6 +256,15 @@ EngineReset
|
|||
dec tmp15
|
||||
bne :loop
|
||||
|
||||
; Set the scanline tables to reasonable default values
|
||||
; ldx #{416*2}-2
|
||||
; lda #0
|
||||
;:sxm_loop
|
||||
; sta StartXMod164Arr,x
|
||||
; dex
|
||||
; dex
|
||||
; bpl :sxm_loop
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
|
80
src/Defs.s
80
src/Defs.s
|
@ -20,6 +20,7 @@ SHR_SCREEN equ $E12000
|
|||
SHR_SCB equ $E19D00
|
||||
SHR_PALETTES equ $E19E00
|
||||
SHR_LINE_WIDTH equ 160
|
||||
SHR_SCREEN_HEIGHT equ 200
|
||||
|
||||
; Direct page locations used by the engine
|
||||
ScreenHeight equ 0 ; Height of the playfield in scan lines
|
||||
|
@ -39,12 +40,12 @@ EngineMode equ 20 ; Defined the mode/capabilities that ar
|
|||
; bit 2: 0 = No static buffer, 1 = Allocation Bank 00 space for a static screen buffer
|
||||
DirtyBits equ 22 ; Identify values that have changed between frames
|
||||
|
||||
BG1DataBank equ 24 ; Data bank that holds BG1 layer data
|
||||
BG1AltBank equ 26 ; Alternate BG1 bank
|
||||
CompileBank0 equ 24 ; Always zero to allow [CompileBank0],y addressing
|
||||
CompileBank equ 26 ; Data bank that holds compiled sprite code
|
||||
|
||||
BlitterDP equ 28 ; Direct page address the holder blitter data
|
||||
BlitterDP equ 28 ; Direct page address that holds blitter data
|
||||
|
||||
OldStartX equ 30
|
||||
OldStartX equ 30 ; Used to track deltas between frames
|
||||
OldStartY equ 32
|
||||
|
||||
LastPatchOffset equ 34 ; Offset into code field that was patched with BRA instructions
|
||||
|
@ -60,7 +61,7 @@ BG1StartYMod208 equ 46
|
|||
OldBG1StartX equ 48
|
||||
OldBG1StartY equ 50
|
||||
|
||||
BG1OffsetIndex equ 52
|
||||
BG1OffsetIndex equ 52 ; Utility index for scanline effect in BG1
|
||||
|
||||
BG0TileOriginX equ 54 ; Coordinate in the tile map that corresponds to the top-left corner
|
||||
BG0TileOriginY equ 56
|
||||
|
@ -72,22 +73,22 @@ BG1TileOriginY equ 64
|
|||
OldBG1TileOriginX equ 66
|
||||
OldBG1TileOriginY equ 68
|
||||
|
||||
TileMapWidth equ 70
|
||||
TileMapWidth equ 70 ; Pointer to memory holding the tile map for the primary background
|
||||
TileMapHeight equ 72
|
||||
TileMapPtr equ 74
|
||||
FringeMapPtr equ 78
|
||||
|
||||
BG1TileMapWidth equ 82
|
||||
BG1TileMapHeight equ 84
|
||||
BG1TileMapPtr equ 86
|
||||
BG1TileMapPtr equ 86 ; Pointer to memory holding the tile map for the secondary background
|
||||
|
||||
SCBArrayPtr equ 90 ; Used for palette binding
|
||||
SpriteBanks equ 94 ; Bank bytes for the sprite data and sprite mask
|
||||
LastRender equ 96 ; Record which render function was last executed
|
||||
; gap
|
||||
CompileBankTop equ 98 ; First free byte i nthe compile bank. Grows upward in memeory.
|
||||
SpriteMap equ 100 ; Bitmap of open sprite slots.
|
||||
ActiveSpriteCount equ 102
|
||||
BankLoad equ 104
|
||||
BG1DataBank equ 104 ; Data bank that holds BG1 layer data
|
||||
TileStoreBankAndBank01 equ 106
|
||||
TileStoreBankAndTileDataBank equ 108
|
||||
TileStoreBankDoubled equ 110
|
||||
|
@ -101,7 +102,9 @@ RenderFlags equ 124 ; Flags passed to the Render() function
|
|||
BG1Scaling equ 126
|
||||
|
||||
activeSpriteList equ 128 ; 32 bytes for the active sprite list (can persist across frames)
|
||||
; tiletmp equ 178 ; 16 bytes of temp storage for the tile renderers
|
||||
|
||||
; Free space from 160 to 192
|
||||
|
||||
blttmp equ 192 ; 32 bytes of local cache/scratch space for blitter
|
||||
|
||||
tmp8 equ 224 ; another 16 bytes of temporary space to be used as scratch
|
||||
|
@ -165,12 +168,16 @@ SPRITE_VBUFF_PTR equ 224 ; 32 bytes of adjusted pointers to VBuf
|
|||
ENGINE_MODE_TWO_LAYER equ $0001
|
||||
ENGINE_MODE_DYN_TILES equ $0002
|
||||
ENGINE_MODE_BNK0_BUFF equ $0004
|
||||
ENGINE_MODE_USER_TOOL equ $8000 ; Communicate if GTE is loaded as a system tool, or a user tool
|
||||
|
||||
; Render flags
|
||||
RENDER_ALT_BG1 equ $0001
|
||||
RENDER_BG1_HORZ_OFFSET equ $0002
|
||||
RENDER_BG1_VERT_OFFSET equ $0004
|
||||
RENDER_BG1_ROTATION equ $0008
|
||||
RENDER_PER_SCANLINE equ $0010
|
||||
RENDER_WITH_SHADOWING equ $0020
|
||||
RENDER_SPRITES_SORTED equ $0040 ; Draw the sprites in y-sorted order. Otherwise, use the index.
|
||||
|
||||
; DirtyBits definitions
|
||||
DIRTY_BIT_BG0_X equ $0001
|
||||
|
@ -181,6 +188,16 @@ DIRTY_BIT_BG0_REFRESH equ $0010
|
|||
DIRTY_BIT_BG1_REFRESH equ $0020
|
||||
DIRTY_BIT_SPRITE_ARRAY equ $0040
|
||||
|
||||
; GetAddress table IDs
|
||||
scanlineHorzOffset equ $0001 ; Table of 416 words, a double-array of scanline offset values. Values must be in range [0, 163]
|
||||
scanlineHorzOffset2 equ $0002 ; Table of 416 words, a double-array of scanline offset values. Values must be in range [0, 163]
|
||||
tileStore equ $0003
|
||||
vblCallback equ $0004 ; User routine to be called by VBL interrupt. Set to $000000 to disconnect
|
||||
|
||||
; CopyPicToBG1 flags
|
||||
COPY_PIC_NORMAL equ $0000 ; Copy into BG1 buffer in "normal mode" treating the buffer as a 164x208 pixmap with stride of 256
|
||||
COPY_PIC_SCANLINE equ $0001 ; Copy in a way to support BG1 + RENDER_PER_SCANLINE. Pixmap is double-width, 327x200 with stride of 327
|
||||
|
||||
; Script definition
|
||||
YIELD equ $8000
|
||||
JUMP equ $4000
|
||||
|
@ -196,25 +213,33 @@ PAD_BUTTON_A equ $0200
|
|||
PAD_KEY_DOWN equ $0400
|
||||
|
||||
; Tile constants
|
||||
; TILE_RESERVED_BIT equ $8000
|
||||
TILE_PRIORITY_BIT equ $4000 ; Put tile on top of sprite
|
||||
TILE_FRINGE_BIT equ $2000 ; Unused
|
||||
TILE_DAMAGED_BIT equ $8000 ; Mark a tile as damaged (internal only)
|
||||
TILE_PRIORITY_BIT equ $4000 ; Put tile on top of sprite (unimplemented)
|
||||
TILE_USER_BIT equ $2000 ; User-defined tile. Execute registered callback.
|
||||
TILE_SOLID_BIT equ $1000 ; Hint bit used in TWO_LAYER_MODE to optimize rendering
|
||||
TILE_DYN_BIT equ $0800 ; Is this a Dynamic Tile?
|
||||
TILE_VFLIP_BIT equ $0400
|
||||
TILE_HFLIP_BIT equ $0200
|
||||
TILE_ID_MASK equ $01FF
|
||||
TILE_CTRL_MASK equ $FE00
|
||||
; TILE_PROC_MASK equ $F800 ; Select tile proc for rendering
|
||||
TILE_CTRL_MASK equ $7E00
|
||||
; TILE_PROC_MASK equ $7800 ; Select tile proc for rendering
|
||||
|
||||
; Sprite constants
|
||||
SPRITE_HIDE equ $2000
|
||||
SPRITE_OVERLAY equ $8000 ; This is an overlay record. Stored as a sprite for render ordering purposes
|
||||
SPRITE_COMPILED equ $4000 ; This is a compiled sprite (SPRITE_DISP points to a routine in the compiled cache bank)
|
||||
SPRITE_HIDE equ $2000 ; Do not render the sprite
|
||||
SPRITE_16X16 equ $1800 ; 16 pixels wide x 16 pixels tall
|
||||
SPRITE_16X8 equ $1000 ; 16 pixels wide x 8 pixels tall
|
||||
SPRITE_8X16 equ $0800 ; 8 pixels wide x 16 pixels tall
|
||||
SPRITE_8X8 equ $0000 ; 8 pixels wide x 8 pixels tall
|
||||
SPRITE_VFLIP equ $0400
|
||||
SPRITE_HFLIP equ $0200
|
||||
SPRITE_VFLIP equ $0400 ; Flip the sprite vertically
|
||||
SPRITE_HFLIP equ $0200 ; Flip the sprite horizontally
|
||||
|
||||
; Overlay bits (aliases of SPRITE_ID bits)
|
||||
OVERLAY_MASKED equ $0000 ; Overlay has a mask, so the background must be draw first
|
||||
OVERLAY_SOLID equ $4000 ; Overlay covers the scan line and is fully opaque
|
||||
OVERLAY_ABOVE equ $0000 ; Overlay is drawn above scanline sprites
|
||||
OVERLAY_BELOW equ $2000 ; Overlay is drawn below scanline sprites
|
||||
|
||||
; Stamp storage parameters
|
||||
VBUFF_STRIDE_BYTES equ {12*4} ; Each line has 4 slots of 16 pixels + 8 buffer pixels
|
||||
|
@ -262,9 +287,26 @@ VBuffArray EXT
|
|||
_stamp_step EXT
|
||||
VBuffVertTableSelect EXT
|
||||
VBuffHorzTableSelect EXT
|
||||
Overlays EXT
|
||||
; Overlays EXT
|
||||
BG1YCache EXT
|
||||
ScalingTables EXT
|
||||
|
||||
;StartXMod164Arr EXT
|
||||
;LastPatchOffsetArr EXT
|
||||
|
||||
_SortedHead EXT
|
||||
_ShadowListCount EXT
|
||||
_ShadowListTop EXT
|
||||
_ShadowListBottom EXT
|
||||
_DirectListCount EXT
|
||||
_DirectListTop EXT
|
||||
_DirectListBottom EXT
|
||||
ObjectListCount EXT
|
||||
ObjectListHead EXT
|
||||
ObjectList EXT
|
||||
StartXMod164Tbl EXT
|
||||
LastOffsetTbl EXT
|
||||
BG1StartXMod164Tbl EXT
|
||||
|
||||
; Tool error codes
|
||||
NO_TIMERS_AVAILABLE equ 10
|
||||
|
|
|
@ -0,0 +1,271 @@
|
|||
; Large, unrolled loops for setting values in the code field that would be used by the Horz.s
|
||||
; and Vert.s code.
|
||||
;
|
||||
; The utility of these functions is that they do not need to do any sort of bank switching and
|
||||
; can update all of the play field lines in a single call. The downside is that they take up
|
||||
; significantly more space, need large auxiliary tables, and must be patched after the code
|
||||
; field memory is allocated.
|
||||
;
|
||||
; Probably still worth it....
|
||||
|
||||
BlitBuff EXT
|
||||
|
||||
; Patch the fast copy routines with the allocated memory addresses
|
||||
InitFastCopies
|
||||
|
||||
; Fist, patch the cttc routine
|
||||
|
||||
ldy #0
|
||||
ldx #0
|
||||
|
||||
:loop1
|
||||
lda BlitBuff+2,y ; Get the bank of each in the accumulatow low byte
|
||||
|
||||
sep #$20
|
||||
]line equ 0
|
||||
lup 16
|
||||
stal cttc_start+{]line*7}+4,x
|
||||
stal cttc_start+{{]line+208}*7}+4,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rep #$20
|
||||
|
||||
txa
|
||||
clc
|
||||
adc #7*16
|
||||
tax
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #4
|
||||
tay
|
||||
|
||||
cpy #13*4
|
||||
bcs *+5
|
||||
brl :loop1
|
||||
|
||||
; Next, patch the two store routines
|
||||
|
||||
ldy #0
|
||||
ldx #0
|
||||
|
||||
:loop2
|
||||
lda BlitBuff+2,y ; Get the bank of each in the accumulatow low byte
|
||||
|
||||
sep #$20
|
||||
]line equ 0
|
||||
lup 16
|
||||
stal store_start+{]line*4}+1,x
|
||||
stal store_start+{{]line+208}*4}+1,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rep #$20
|
||||
|
||||
txa
|
||||
clc
|
||||
adc #4*16
|
||||
tax
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #4
|
||||
tay
|
||||
|
||||
cpy #13*4
|
||||
bcs *+5
|
||||
brl :loop2
|
||||
|
||||
rtl
|
||||
|
||||
|
||||
; Function to load data from an array and store in the code field. Assume that the
|
||||
; bank register is already set to the bank of the srcAddr data
|
||||
srcAddr equ 0
|
||||
destOffset equ 2
|
||||
|
||||
CopyTblToCode
|
||||
ldal entry_7,x ; This is the entry point
|
||||
stal cttc_jump+1
|
||||
|
||||
txa ; Set the Y register to srcAddr - 2*start to compensate for the
|
||||
eor #$FFFF ; offset in the code. This does mean that the array we are copying
|
||||
sec ; cannot by near the beginning of the bank
|
||||
adc srcAddr
|
||||
tyx ; put the ending offset in X
|
||||
tay
|
||||
|
||||
ldal entry_7,x
|
||||
tax
|
||||
lda #$0060
|
||||
stal {cttc_start&$FF0000}+3,x ; patch at the next STAL instruction because the high byte is always zero
|
||||
|
||||
ldx destOffset ; byte offset within each line
|
||||
cttc_jump jsr $0000
|
||||
|
||||
lda #$009F ; restore the STAL opcode
|
||||
stal {cttc_start&$FF0000}+3,x
|
||||
|
||||
rtl
|
||||
|
||||
; Define the 416 addresses for each copy
|
||||
entry_7
|
||||
]line equ 0
|
||||
lup 416
|
||||
da cttc_start+{]line*7}
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
; Generate the code that performs the copy.
|
||||
cttc_unit mac
|
||||
lda: {]1*32}+{]2*2},y
|
||||
stal $000000+{]2*$1000},x
|
||||
<<<
|
||||
|
||||
cttc_start
|
||||
]bank equ 0
|
||||
lup 26
|
||||
cttc_unit ]bank;0
|
||||
cttc_unit ]bank;1
|
||||
cttc_unit ]bank;2
|
||||
cttc_unit ]bank;3
|
||||
cttc_unit ]bank;4
|
||||
cttc_unit ]bank;5
|
||||
cttc_unit ]bank;6
|
||||
cttc_unit ]bank;7
|
||||
cttc_unit ]bank;8
|
||||
cttc_unit ]bank;9
|
||||
cttc_unit ]bank;10
|
||||
cttc_unit ]bank;11
|
||||
cttc_unit ]bank;12
|
||||
cttc_unit ]bank;13
|
||||
cttc_unit ]bank;14
|
||||
cttc_unit ]bank;15
|
||||
]bank equ ]bank+1
|
||||
--^
|
||||
rts
|
||||
|
||||
Store8Bits
|
||||
txa
|
||||
asl
|
||||
adc #store_start
|
||||
stal s8b_jump+1
|
||||
|
||||
tya
|
||||
asl
|
||||
tax
|
||||
lda #$0060
|
||||
stal {store_start&$FF0000},x
|
||||
|
||||
ldx destOffset ; byte offset within each line
|
||||
lda srcAddr
|
||||
sep #$20
|
||||
s8b_jump jsr $0000
|
||||
|
||||
lda #$9F ; restore the STAL opcode
|
||||
stal {store_start&$FF0000},x
|
||||
rep #$20
|
||||
|
||||
rtl
|
||||
|
||||
Store16Bits
|
||||
txa
|
||||
asl
|
||||
adc #store_start
|
||||
stal s16b_jump+1
|
||||
|
||||
tya
|
||||
asl
|
||||
tax
|
||||
lda #$0060
|
||||
stal {store_start&$FF0000},x
|
||||
|
||||
ldx destOffset ; byte offset within each line
|
||||
lda srcAddr
|
||||
s16b_jump jsr $0000
|
||||
|
||||
lda #$009F ; restore the STAL opcode
|
||||
stal {store_start&$FF0000},x
|
||||
rtl
|
||||
|
||||
store_start
|
||||
lup 26
|
||||
stal $000000,x
|
||||
stal $001000,x
|
||||
stal $002000,x
|
||||
stal $003000,x
|
||||
stal $004000,x
|
||||
stal $005000,x
|
||||
stal $006000,x
|
||||
stal $007000,x
|
||||
stal $008000,x
|
||||
stal $009000,x
|
||||
stal $00A000,x
|
||||
stal $00B000,x
|
||||
stal $00C000,x
|
||||
stal $00D000,x
|
||||
stal $00E000,x
|
||||
stal $00F000,x
|
||||
--^
|
||||
rts
|
||||
|
||||
|
||||
CodeCopy8
|
||||
txa
|
||||
asl
|
||||
adc #store_start
|
||||
stal cc8_jump+1
|
||||
|
||||
tya
|
||||
asl
|
||||
tax
|
||||
lda #$0060
|
||||
stal {store8_start&$FF0000},x
|
||||
|
||||
ldx destOffset ; byte offset within each line
|
||||
lda srcAddr
|
||||
cc8_jump jsr $0000
|
||||
|
||||
lda #$009F ; restore the STAL opcode
|
||||
stal {store8_start&$FF0000},x
|
||||
rtl
|
||||
|
||||
store8_start
|
||||
lup 26
|
||||
pea $0000
|
||||
plb
|
||||
plb
|
||||
|
||||
lda $0000,y
|
||||
stal $000000,x
|
||||
lda $0000,y
|
||||
stal $001000,x
|
||||
lda $0000,y
|
||||
stal $002000,x
|
||||
lda $0000,y
|
||||
stal $003000,x
|
||||
lda $0000,y
|
||||
stal $004000,x
|
||||
lda $0000,y
|
||||
stal $005000,x
|
||||
lda $0000,y
|
||||
stal $006000,x
|
||||
lda $0000,y
|
||||
stal $007000,x
|
||||
lda $0000,y
|
||||
stal $008000,x
|
||||
lda $0000,y
|
||||
stal $009000,x
|
||||
lda $0000,y
|
||||
stal $00A000,x
|
||||
lda $0000,y
|
||||
stal $00B000,x
|
||||
lda $0000,y
|
||||
stal $00C000,x
|
||||
lda $C000,y
|
||||
stal $00D000,x
|
||||
lda $E000,y
|
||||
stal $00E000,x
|
||||
lda $F000,y
|
||||
stal $00F000,x
|
||||
--^
|
||||
rts
|
|
@ -4,13 +4,15 @@ InitGraphics
|
|||
jsr _ShadowOn
|
||||
jsr _GrafOn
|
||||
lda #0
|
||||
jsr _ClearToColor
|
||||
lda #0
|
||||
jsr _SetSCBs
|
||||
ldx #DefaultPalette
|
||||
lda #0
|
||||
jsr _SetPalette
|
||||
|
||||
ldx #SHR_LINE_WIDTH
|
||||
ldy #SHR_SCREEN_HEIGHT
|
||||
jsr _SetScreenMode
|
||||
|
||||
jsr _InitBG0 ; Initialize the background layer
|
||||
|
||||
lda EngineMode
|
||||
|
@ -40,7 +42,7 @@ InitGraphics
|
|||
; 9. Agony (Amiga) : 36 x 24 288 x 192 (27,648 bytes ( 86.4%))
|
||||
; 10. Atari Lynx : 20 x 13 160 x 102 (8,160 bytes ( 25.5%))
|
||||
;
|
||||
; X = mode number OR width in pixels (must be multiple of 2)
|
||||
; X = mode number OR width in bytes
|
||||
; Y = height in pixels (if X > 8)
|
||||
_SetScreenMode
|
||||
cpx #11
|
||||
|
@ -54,25 +56,23 @@ _SetScreenMode
|
|||
lda ScreenModeWidth,x
|
||||
tax
|
||||
|
||||
:direct cpy #201
|
||||
:direct cpy #SHR_SCREEN_HEIGHT+1
|
||||
bcs :exit
|
||||
|
||||
cpx #321
|
||||
cpx #SHR_LINE_WIDTH+1
|
||||
bcs :exit
|
||||
|
||||
txa
|
||||
lsr
|
||||
pha ; Save X (width / 2) and Y (height)
|
||||
phx ; Save X (width) and Y (height)
|
||||
phy
|
||||
|
||||
lda #160 ; Center the screen
|
||||
lda #SHR_LINE_WIDTH ; Center the screen
|
||||
sec
|
||||
sbc 3,s
|
||||
lsr
|
||||
xba
|
||||
pha ; Save half the origin coordinate
|
||||
|
||||
lda #200
|
||||
lda #SHR_SCREEN_HEIGHT
|
||||
sec
|
||||
sbc 3,s ; This is now Y because of the PHA above
|
||||
lsr
|
||||
|
|
27
src/Master.s
27
src/Master.s
|
@ -2,7 +2,7 @@
|
|||
|
||||
TYP $BA ; Tool set file
|
||||
DSK Tool160
|
||||
XPL
|
||||
XPL
|
||||
|
||||
; Main toolbox interface and code
|
||||
|
||||
|
@ -11,35 +11,42 @@
|
|||
|
||||
; 64KB Tile Memory
|
||||
|
||||
ASM static\TileData.s
|
||||
KND #$1001 ; Type and Attributes ($10=Static,$01=Data)
|
||||
ASM static/TileData.s
|
||||
KND #$1101 ; Type and Attributes ($10=Static,$01=Data)
|
||||
ALI BANK
|
||||
SNA TDATA
|
||||
|
||||
; 64KB Sprite Plane Data
|
||||
|
||||
ASM static\SprData.s
|
||||
KND #$1001 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ASM static/SprData.s
|
||||
KND #$1101 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ALI BANK
|
||||
SNA SDATA
|
||||
|
||||
; 64KB Sprite Mask Data
|
||||
|
||||
ASM static\SprMask.s
|
||||
KND #$1001 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ASM static/SprMask.s
|
||||
KND #$1101 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ALI BANK
|
||||
SNA SMASK
|
||||
|
||||
; 64KB Tile Store
|
||||
|
||||
ASM static\TileStore.s
|
||||
KND #$1001 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ASM static/TileStore.s
|
||||
KND #$1101 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ALI BANK
|
||||
SNA TSTORE
|
||||
|
||||
; 64KB Rotation Data Tables
|
||||
|
||||
ASM RotData.s
|
||||
KND #$1001 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
KND #$1101 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
ALI BANK
|
||||
SNA ROTDATA
|
||||
|
||||
; Additional code
|
||||
|
||||
; ASM FastCopies.s
|
||||
; KND #$1101 ; Type and Attributes ($11=Static+Bank Relative,$01=Data)
|
||||
; ALI BANK
|
||||
; SNA FASTCPY
|
||||
|
|
17
src/Memory.s
17
src/Memory.s
|
@ -28,9 +28,7 @@ InitMemory lda EngineMode
|
|||
_NewHandle ; returns LONG Handle on stack
|
||||
plx ; base address of the new handle
|
||||
pla ; high address 00XX of the new handle (bank)
|
||||
; _Deref
|
||||
; stx Buff00
|
||||
; sta Buff00+2
|
||||
|
||||
:no_bnk0_buff
|
||||
|
||||
PushLong #0 ; space for result
|
||||
|
@ -41,9 +39,6 @@ InitMemory lda EngineMode
|
|||
_NewHandle ; returns LONG Handle on stack
|
||||
plx ; base address of the new handle
|
||||
pla ; high address 00XX of the new handle (bank)
|
||||
; _Deref
|
||||
; stx Buff01
|
||||
; sta Buff01+2
|
||||
|
||||
PushLong #0 ; space for result
|
||||
|
||||
|
@ -64,16 +59,20 @@ InitMemory lda EngineMode
|
|||
_Deref
|
||||
stx BlitterDP
|
||||
|
||||
; Allocate banks of memory for BG1
|
||||
; Allocate banks of memory for BG1. If the user wants to swap between multiple BG1 banks, then they need to be allocated
|
||||
; outside of GTE and selected using the GTESetBG1Bank() function. Passing a zero for that function's argument will
|
||||
; always set the bank to the allocated bank number. Bank 00 and Bank 01 are illegal values.
|
||||
|
||||
lda EngineMode
|
||||
bit #ENGINE_MODE_TWO_LAYER
|
||||
beq :no_bg1
|
||||
jsr AllocOneBank2
|
||||
sta BG1DataBank
|
||||
:no_bg1
|
||||
|
||||
jsr AllocOneBank2
|
||||
sta BG1AltBank
|
||||
:no_bg1
|
||||
sta CompileBank
|
||||
stz CompileBank0
|
||||
|
||||
; Allocate the 13 banks of memory we need and store in double-length array
|
||||
]step equ 0
|
||||
|
|
|
@ -93,3 +93,43 @@ Possibilities
|
|||
lda 0000,y
|
||||
lda 0002,y
|
||||
...
|
||||
|
||||
= HOWTO: Custom tiles =
|
||||
|
||||
pea #^MyTileRenderer ; Define the callback function
|
||||
pea #MyTileRenderer
|
||||
_GTESetCustomTileCallback
|
||||
|
||||
pea 0 ; Put tiles with the TILE_USER_BIT set
|
||||
pea 0
|
||||
pea TILE_ID+TILE_USER_BIT
|
||||
_GTESetTile
|
||||
|
||||
; On entry
|
||||
;
|
||||
; A = Tile Id. Use this to select what to draw
|
||||
; Y = Address of tile in the code field
|
||||
; X = Tile Store array offset
|
||||
; B = code field bank
|
||||
;
|
||||
; Use absolute addressing to fill in the code bank and address offsets $0000, $0003, $1000, $1003, ..., $7000, $7003. If
|
||||
; code needs to create snippets, it can be loaded from the tile store array by using the address returned from
|
||||
; GTEGetAddress(tileStoreJmpAddr)
|
||||
;
|
||||
; User-defined tiles are always marked as damaged.
|
||||
|
||||
MyTileRenderer
|
||||
lda #00A3 ; Inserts LDA 00,s / PHA code to show a static background from Bank 0
|
||||
sta: $0000,y
|
||||
sta: $0003,y
|
||||
sta: $1000,y
|
||||
sta: $1003,y
|
||||
...
|
||||
lda #$4800
|
||||
sta: $0001,y
|
||||
sta: $0004,y
|
||||
sta: $1001,y
|
||||
sta: $1004,y
|
||||
...
|
||||
rtl ; Must do a long return
|
||||
|
611
src/Render.s
611
src/Render.s
|
@ -8,8 +8,15 @@
|
|||
; and internal data structure to properly render the play field. Then the update pipeline is
|
||||
; executed.
|
||||
;
|
||||
; Everything is composited into the tiles in the playfield and then the screen is rendered in
|
||||
; a single pass.
|
||||
; There are two major rendering modes: a composited mode and a scanline mode. The composited mode
|
||||
; will render all of the sprites into the playfield tiles, and then perform a single blit to update
|
||||
; the entire playfield. The scanline mode utilized shadowing and blits the background scanlines
|
||||
; on sprite lines first, then draws the sprites and finally exposes the updated scanlines.
|
||||
;
|
||||
; The composited mode has the advantages of being able to render sprites behind tile data as well
|
||||
; as avoiding most overdraw. The scanline mode is able to draw sprites correctly even when scanline
|
||||
; effect are used on the background and has lower overhead, which can make it faster in some cases,
|
||||
; even with the additional overdraw.
|
||||
;
|
||||
; TODO -- actually check the dirty bits and be selective on what gets updated. For example, if
|
||||
; only the Y position changes, then we should only need to set new values on the
|
||||
|
@ -51,9 +58,10 @@ _Render
|
|||
jsr _UpdateBG0TileMap ; and the tile maps. These subroutines build up a list of tiles
|
||||
; jsr _UpdateBG1TileMap ; that need to be updated in the code field
|
||||
|
||||
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
|
||||
|
||||
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
|
||||
jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode
|
||||
|
||||
lda #RENDER_BG1_ROTATION
|
||||
bit RenderFlags
|
||||
bne :skip_bg1_x
|
||||
|
@ -63,7 +71,7 @@ _Render
|
|||
; The code fields are locked in now and ready to be rendered. See if there is an overlay or any
|
||||
; other reason to render with shadowing off. Otherwise, just do things quickly.
|
||||
|
||||
lda Overlays
|
||||
lda Overlays+OVERLAY_ID
|
||||
beq :no_ovrly
|
||||
|
||||
jsr _ShadowOff
|
||||
|
@ -72,8 +80,9 @@ _Render
|
|||
; optimization that can be done here is that the lines can be rendered in any order
|
||||
; since it is not shown on-screen yet.
|
||||
|
||||
ldx Overlays+2 ; Blit the full virtual buffer to the screen
|
||||
ldy Overlays+4
|
||||
ldx Overlays+OVERLAY_TOP ; Blit the full virtual buffer to the screen
|
||||
ldy Overlays+OVERLAY_BOTTOM
|
||||
iny
|
||||
jsr _BltRange
|
||||
|
||||
; Turn shadowing back on
|
||||
|
@ -82,14 +91,10 @@ _Render
|
|||
|
||||
; Now render all of the remaining lines in top-to-bottom (or bottom-to-top) order
|
||||
|
||||
ldx #0
|
||||
ldy Overlays+2
|
||||
beq :skip
|
||||
jsr _BltRange
|
||||
:skip
|
||||
jsr _DoOverlay
|
||||
|
||||
ldx Overlays+4
|
||||
ldx Overlays+OVERLAY_BOTTOM
|
||||
inx
|
||||
cpx ScreenHeight
|
||||
beq :done
|
||||
ldy ScreenHeight
|
||||
|
@ -130,15 +135,16 @@ _Render
|
|||
:no_removal
|
||||
rts
|
||||
|
||||
; Small helper function to draw a single overlay
|
||||
_DoOverlay
|
||||
lda Overlays+6
|
||||
lda Overlays+OVERLAY_PROC
|
||||
stal :disp+1
|
||||
lda Overlays+7
|
||||
lda Overlays+OVERLAY_PROC+1
|
||||
stal :disp+2
|
||||
|
||||
lda ScreenY0 ; pass the address of the first line of the overlay
|
||||
clc
|
||||
adc Overlays+2
|
||||
adc Overlays+OVERLAY_TOP
|
||||
asl
|
||||
tax
|
||||
lda ScreenAddr,x
|
||||
|
@ -147,6 +153,223 @@ _DoOverlay
|
|||
:disp jsl $000000
|
||||
rts
|
||||
|
||||
|
||||
; Use the per-scanline tables to set the screen. This is really meant to be used without the built-in tilemap
|
||||
; support and is more of a low-level way to control the background rendering
|
||||
_RenderScanlines
|
||||
lda BG1YTable ; Make sure we're in the right mode (0 = scanline mode, $1800 = normal mode)
|
||||
beq :ytbl_ok
|
||||
lda #1
|
||||
jsr _ResetBG1YTable
|
||||
:ytbl_ok
|
||||
|
||||
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
|
||||
jsr _ApplyScanlineBG1YPos ; Set the y-register values of the blitter
|
||||
|
||||
jsr _ApplyBG0XPosPre
|
||||
jsr _ApplyBG1XPosPre
|
||||
|
||||
jsr _ApplyScanlineBG0XPos ; Patch the code field instructions with exit BRA opcode
|
||||
jsr _ApplyScanlineBG1XPos
|
||||
|
||||
jsr _FilterObjectList ; Walk the sorted list and create an array of objects that need to be rendered
|
||||
|
||||
jsr _ShadowOff ; Turn off shadowing and draw all the scanlines with sprites on them
|
||||
jsr _DrawObjShadow ; Draw the background
|
||||
jsr _DrawDirectSprites ; Draw the sprites directly to the Bank $01 graphics buffer (skipping the render-to-tile step)
|
||||
|
||||
jsr _ShadowOn ; Turn shadowing back on
|
||||
jsr _DrawFinalPass ; Expose the shadowed areas and draw overlays
|
||||
|
||||
lda StartYMod208 ; Restore the fields back to their original state
|
||||
ldx ScreenHeight
|
||||
jsr _RestoreScanlineBG0Opcodes
|
||||
|
||||
lda StartY
|
||||
sta OldStartY
|
||||
lda StartX
|
||||
sta OldStartX
|
||||
|
||||
lda BG1StartY
|
||||
sta OldBG1StartY
|
||||
lda BG1StartX
|
||||
sta OldBG1StartX
|
||||
|
||||
stz DirtyBits
|
||||
stz LastRender ; Mark that a full render was just performed
|
||||
|
||||
lda SpriteRemovedFlag ; If any sprite was removed, set the rebuild flag
|
||||
beq :no_removal
|
||||
lda #DIRTY_BIT_SPRITE_ARRAY
|
||||
sta DirtyBits
|
||||
:no_removal
|
||||
rts
|
||||
|
||||
|
||||
; After the sprites have been filtered, we have a linked list with all of the contiguous sprite regions merged together, so
|
||||
; when provessing this list we really only have to consider complications from overlays.
|
||||
;
|
||||
; Pseudo-code
|
||||
;
|
||||
; 0. Set the cursor to the top of the screen
|
||||
; 1. Load the next segment
|
||||
; a. If no segments, just draw the full screen
|
||||
; 2. Draw the background from the cursor to the top of the current segment
|
||||
; 3. If the current segment is a sprite
|
||||
; a. Peek at the next segment
|
||||
; b. If no more segments, then finish
|
||||
; c. If it's past the bottom, PEI slam the current segment and go to [1]
|
||||
; d. Must be an overlay
|
||||
; i. PEI slam up to the overlay top
|
||||
; ii. Does the sprite extend past the overlay? If yes, split the sprite and insert into the list
|
||||
; iii. Go to [1]
|
||||
; 4. If the current segment is an overlay
|
||||
; a. Peek at the next segment
|
||||
; b. If no more segments, then finish
|
||||
; c. If it's past the bottom, draw the overlay and go to [1]
|
||||
; d. Must be a sprite
|
||||
; i. Draw the overlay
|
||||
; ii. Change the sprite segment to start after the overlay
|
||||
; iii. Go to [1]
|
||||
_DrawFinalPass
|
||||
:cursor equ tmp8
|
||||
:bottom equ tmp9
|
||||
|
||||
stz :cursor
|
||||
ldy #0
|
||||
cpy ObjectListCount
|
||||
bne :enter
|
||||
|
||||
ldx #0 ; If there are no object to render, just draw the screen
|
||||
ldy ScreenHeight
|
||||
jmp _BltRange
|
||||
|
||||
:enter
|
||||
ldx ObjectList+OL_INDEX,y ; Load the index of the next object record
|
||||
|
||||
; Draw the background up to the top line of the next object
|
||||
|
||||
phxy
|
||||
ldy _Sprites+SPRITE_CLIP_TOP,x
|
||||
ldx :cursor
|
||||
sty :cursor ; Update the cursor since we have the value
|
||||
jsr _BltRange
|
||||
plyx
|
||||
|
||||
:_oloop
|
||||
lda _Sprites+SPRITE_CLIP_BOTTOM,x
|
||||
sta :bottom
|
||||
|
||||
; Load the ID to see what kind of object comes next
|
||||
|
||||
lda _Sprites+SPRITE_ID,x ; See if we are processing an overlay or a sprite region
|
||||
bit #SPRITE_OVERLAY
|
||||
jne :_overlay
|
||||
|
||||
:_sprite
|
||||
iny
|
||||
iny
|
||||
cpy ObjectListCount
|
||||
jeq :_sprite_end ; If this is the last object, end now on the sprite
|
||||
|
||||
ldx ObjectList+OL_INDEX,y ; Load the index of the next item
|
||||
lda :bottom
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,x
|
||||
bcs :_smerge ; If the prior sprite ends before this object, then handle it
|
||||
|
||||
phxy
|
||||
ldy _Sprites+SPRITE_CLIP_TOP,x ; A = :bottom, so load the top of the next object and
|
||||
sty :bottom ; save it as it is the bottom after the PEISlam
|
||||
|
||||
ldx :cursor ; X = :cursor
|
||||
sta :cursor ; The current :bottom becomes the :cursor after the PEISlam
|
||||
tay ; Y = :bottom
|
||||
jsr _PEISlam
|
||||
ldx :cursor ; This is the previous :bottom value
|
||||
ldy :bottom ; This is the SPRITE_CLIP_TOP,x value
|
||||
sty :cursor
|
||||
jsr _BltRange
|
||||
plyx
|
||||
brl :_oloop ; Branch back, it's like starting from from scratch
|
||||
|
||||
:_smerge
|
||||
lda _Sprites+SPRITE_ID,x ; Before we merge, need to know if objects are compatible
|
||||
bit #SPRITE_OVERLAY
|
||||
bne :_somerge
|
||||
|
||||
lda _Sprites+SPRITE_CLIP_BOTTOM,x ; Can be merged, so pick the largest bottom value and
|
||||
max :bottom ; continue on as a sprite
|
||||
sta :bottom
|
||||
brl :_sprite
|
||||
|
||||
:_somerge
|
||||
phxy
|
||||
ldy _Sprites+SPRITE_CLIP_TOP,x ; PEI Slam to the top of the overlay (:bottom is greater than this value)
|
||||
ldx :cursor
|
||||
sty :cursor
|
||||
; brk $44
|
||||
jsr _PEISlam
|
||||
lda 3,s ; Retrieve the sprite index
|
||||
tax
|
||||
jsr _DrawOverlay
|
||||
plyx
|
||||
|
||||
lda _Sprites+SPRITE_CLIP_BOTTOM,x ; This is how far we've drawn. Check to see if we're beyond the current :bottom
|
||||
sta :cursor
|
||||
cmp :bottom
|
||||
jcc :_sprite ; Previous sprite extends past the overlay, continue
|
||||
|
||||
; The overlay can cause the cursor to jump ahead an arbitrary distance. We need to continue to scan through the list until
|
||||
; we find an item that has a bottom greater than the current :cursor
|
||||
:_so_loop
|
||||
iny
|
||||
iny
|
||||
cpy ObjectListCount
|
||||
beq :_end
|
||||
|
||||
ldx ObjectList+OL_INDEX,y
|
||||
lda :cursor
|
||||
cmp _Sprites+SPRITE_CLIP_BOTTOM,x
|
||||
bcs :_so_loop
|
||||
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,x ; Check to see if there is any background that need to be drawn
|
||||
jcs :_oloop ; If not, go back the see what kind of object it is
|
||||
|
||||
phxy
|
||||
ldy _Sprites+SPRITE_CLIP_TOP,x
|
||||
ldx :cursor
|
||||
sty :cursor
|
||||
jsr _BltRange
|
||||
plyx
|
||||
brl :_oloop
|
||||
|
||||
; If the last item is a sprite, do a PEI slam from the cursor to the sprite bottom and then blit any remaining
|
||||
; backround
|
||||
:_sprite_end
|
||||
ldx :cursor
|
||||
ldy :bottom
|
||||
jsr _PEISlam
|
||||
ldx :bottom
|
||||
ldy ScreenHeight
|
||||
jmp _BltRange
|
||||
|
||||
; If there are no more items to process, but we haven't reached the end of the screen, blit the rest of the
|
||||
; background
|
||||
:_end
|
||||
ldx :cursor
|
||||
ldy ScreenHeight
|
||||
jmp _BltRange
|
||||
|
||||
; An overlay is a bit easier. It just needs to be rendered and then advance to the next object that's not
|
||||
; covered by it
|
||||
:_overlay
|
||||
phxy
|
||||
jsr _DrawOverlay ; Draw the overlay
|
||||
plyx
|
||||
lda :bottom
|
||||
sta :cursor
|
||||
brl :_so_loop
|
||||
|
||||
; Run through all of the tiles on the DirtyTile list and render them
|
||||
_ApplyTiles
|
||||
ldx DirtyTileCount
|
||||
|
@ -213,3 +436,361 @@ _ApplyDirtyTiles
|
|||
stz DirtyTileCount ; Reset the dirty tile count
|
||||
rts
|
||||
|
||||
; This rendering mode turns off shadowing and draws all of the relevant background lines and then
|
||||
; draws sprites on top of the background before turning shadowing on and exposing the lines to the
|
||||
; screen. Even though entire lines are drawn twice, it's so efficient that it is often faster
|
||||
; than using all of the logic to draw/erase tiles in the TileBuffer, even though less visible words
|
||||
; are touched.
|
||||
;
|
||||
; This mode is also necessary if per-scanling rendering is used since sprites would not look correct
|
||||
; if each line had independent offsets.
|
||||
_RenderWithShadowing
|
||||
sta RenderFlags
|
||||
jsr _DoTimers ; Run any pending timer tasks
|
||||
|
||||
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
|
||||
jsr _ApplyBG1YPos ; Set the y-register values of the blitter
|
||||
|
||||
; _ApplyBG0Xpos need to be split because we have to set the offsets, then draw in any updated tiles, and
|
||||
; finally patch out the code field. Right now, the BRA operand is getting overwritten by tile data.
|
||||
|
||||
jsr _ApplyBG0XPosPre
|
||||
jsr _ApplyBG1XPosPre
|
||||
|
||||
jsr _UpdateBG0TileMap ; and the tile maps. These subroutines build up a list of tiles
|
||||
; jsr _UpdateBG1TileMap ; that need to be updated in the code field
|
||||
|
||||
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
|
||||
|
||||
jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode
|
||||
jsr _ApplyBG1XPos ; Update the direct page value based on the horizontal position
|
||||
|
||||
; At this point, everything in the background has been rendered into the code field. Next, we need
|
||||
; to create priority lists of scanline ranges.
|
||||
|
||||
jsr _FilterObjectList ; Walk the sorted list and create an array of objects that need to be rendered
|
||||
|
||||
jsr _ShadowOff ; Turn off shadowing and draw all the scanlines with sprites on them
|
||||
jsr _DrawObjShadow ; Draw the background
|
||||
jsr _DrawDirectSprites ; Draw the sprites directly to the Bank $01 graphics buffer (skipping the render-to-tile step)
|
||||
|
||||
jsr _ShadowOn ; Turn shadowing back on
|
||||
jsr _DrawFinalPass
|
||||
|
||||
lda StartYMod208 ; Restore the fields back to their original state
|
||||
ldx ScreenHeight
|
||||
jsr _RestoreBG0Opcodes
|
||||
|
||||
lda StartY
|
||||
sta OldStartY
|
||||
lda StartX
|
||||
sta OldStartX
|
||||
|
||||
lda BG1StartY
|
||||
sta OldBG1StartY
|
||||
lda BG1StartX
|
||||
sta OldBG1StartX
|
||||
|
||||
stz DirtyBits
|
||||
stz LastRender ; Mark that a full render was just performed
|
||||
|
||||
lda SpriteRemovedFlag ; If any sprite was removed, set the rebuild flag
|
||||
beq :no_removal
|
||||
lda #DIRTY_BIT_SPRITE_ARRAY
|
||||
sta DirtyBits
|
||||
:no_removal
|
||||
rts
|
||||
|
||||
; Run through the list of sprites that are not OFFSCREEN and not OVERLAYS and draw them directly to the graphics screen. We can use
|
||||
; compiled sprites here, with limitations.
|
||||
_DrawDirectSprites
|
||||
lda RenderFlags
|
||||
bit #RENDER_SPRITES_SORTED
|
||||
bne :sorted
|
||||
|
||||
; Shift through the sprites
|
||||
|
||||
lda SpriteMap
|
||||
beq :empty
|
||||
sta tmp15
|
||||
ldx #0
|
||||
|
||||
:iloop
|
||||
lsr tmp15
|
||||
bcc :next
|
||||
|
||||
phx
|
||||
jsr _DrawStampToScreen
|
||||
plx
|
||||
|
||||
:next inx
|
||||
inx
|
||||
lda tmp15
|
||||
bne :iloop
|
||||
rts
|
||||
|
||||
:sorted
|
||||
ldx _SortedHead
|
||||
bmi :empty
|
||||
|
||||
:loop
|
||||
phx
|
||||
jsr _DrawStampToScreen
|
||||
plx
|
||||
|
||||
lda _Sprites+SORTED_NEXT,x ; If there another sprite in the list?
|
||||
tax
|
||||
bpl :loop
|
||||
:empty
|
||||
rts
|
||||
|
||||
|
||||
; Run through the sorted list and perform a final render the jumps between calling _PEISlam for shadowed lines,
|
||||
; _BltRange for clean backgrounds and Overlays as needed.
|
||||
;
|
||||
; The trick here is to merge runs of shared render types.
|
||||
;
|
||||
; Loop invariant: X-register is the current object index, Y-register is the next object index
|
||||
;
|
||||
; TODO: This does not yet handle the case of a narrow overlay in the middle of a sprite. The second half of the sprite will not be exposed
|
||||
; by a PEISlam.
|
||||
;
|
||||
; e.g. |--- Overlay ---|
|
||||
; |-------------- Sprite ----------------|
|
||||
;
|
||||
; Output Should be |-- PEI --||--- Overlay ---||--- PEI --|
|
||||
; But currently is |-- PEI --||--- Overlay ---|
|
||||
;
|
||||
; The conceptual model of this routine is that it toggles between BltRange and PEISlam modes, but overlays are special and get drawn
|
||||
; immediately but don't change the mode.
|
||||
;
|
||||
; General case to handle is this
|
||||
;
|
||||
; 0 1 2 3 4 5 6 7 8 9
|
||||
; |------ sprite ---------| = A
|
||||
; |-- overlay ------| = B
|
||||
; |-- sprite -| = C
|
||||
; |--- sprite ---| = D
|
||||
;
|
||||
; To handle this for each, we need to be able to slice off a piece of a sprite or overlay and insert it into the list for
|
||||
; handling later. In this case, after the range [0, 1] is exposed for A, it should be dropped and moved like this
|
||||
;
|
||||
; 0 1 2 3 4 5 6 7 8 9
|
||||
; |-- overlay ------| = B
|
||||
; |-- sprite -| = C
|
||||
; |--- sprite ---| = D
|
||||
; |--| = A
|
||||
;
|
||||
; We can't alter that actual sorted list of items, so we create a reduced list which allows items to be filtered and
|
||||
; to keep a simple, single-linked list
|
||||
EOL equ $FFFF
|
||||
|
||||
|
||||
; New approach here. Walk the sorted, double linked list and copy the IDs into an array. There is
|
||||
; a parallel structure to use later, but this is the easiest thing to work with
|
||||
_FilterObjectList
|
||||
ldy #0
|
||||
ldx _SortedHead ; Walk the list
|
||||
bra :entry
|
||||
|
||||
:loop
|
||||
txa
|
||||
sta ObjectList+OL_INDEX,y
|
||||
iny
|
||||
iny
|
||||
|
||||
lda _Sprites+SORTED_NEXT,x
|
||||
tax
|
||||
|
||||
:entry
|
||||
jsr _GetNextItem ; Get the first item from the list
|
||||
cpx #EOL
|
||||
bne :loop ; Exit if there are no more items
|
||||
|
||||
sty ObjectListCount
|
||||
rts
|
||||
|
||||
_DrawObjShadow
|
||||
:top equ tmp8
|
||||
:bottom equ tmp9
|
||||
|
||||
ldy #0
|
||||
cpy ObjectListCount ; Exit if the list of objects is empty
|
||||
beq :exit
|
||||
|
||||
; Initialize with the record
|
||||
|
||||
ldx ObjectList+OL_INDEX,y
|
||||
|
||||
:loop
|
||||
lda _Sprites+SPRITE_CLIP_TOP,x ; Get the top scanline
|
||||
sta :top
|
||||
lda _Sprites+SPRITE_CLIP_BOTTOM,x
|
||||
:skip sta :bottom
|
||||
|
||||
; Advance to the next record.
|
||||
|
||||
iny
|
||||
iny
|
||||
cpy ObjectListCount ; Is this the last item
|
||||
beq :done
|
||||
|
||||
; Check to see if the two items overlap
|
||||
|
||||
ldx ObjectList+OL_INDEX,y
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,x ; Compare to the top line of the next item
|
||||
bcc :no_merge
|
||||
|
||||
max _Sprites+SPRITE_CLIP_BOTTOM,x ; Keep the largest of the two bottom values
|
||||
bra :skip
|
||||
|
||||
:no_merge
|
||||
phx
|
||||
phy
|
||||
ldx :top
|
||||
ldy :bottom
|
||||
jsr _BltRange
|
||||
ply
|
||||
plx
|
||||
bra :loop
|
||||
:exit
|
||||
rts
|
||||
|
||||
:done
|
||||
ldx :top ; X = top line
|
||||
ldy :bottom ; Y = bottom line
|
||||
jmp _BltRange ; If so, draw the background and return
|
||||
|
||||
;:loop
|
||||
; Check if the current node and the next node are both sprites and, if they overlap, merge their ranges
|
||||
; lda _Sprites+SPRITE_ID,x
|
||||
; ora ObjectList+OL_SPRITE_ID,y
|
||||
; and #SPRITE_OVERLAY
|
||||
; bne :no_merge;
|
||||
|
||||
; lda ObjectList+OL_CLIP_BOTTOM,y
|
||||
; cmp _Sprites+SPRITE_CLIP_TOP,x
|
||||
; bcc :no_merge
|
||||
|
||||
; lda _Sprites+SPRITE_CLIP_BOTTOM,x
|
||||
; max ObjectList+OL_CLIP_BOTTOM,y
|
||||
; sta ObjectList+OL_CLIP_BOTTOM,y
|
||||
; bra :skip
|
||||
|
||||
;:no_merge
|
||||
; iny
|
||||
; iny
|
||||
; tya
|
||||
; sta ObjectList+OL_NEXT-2,y ; Store link to this record in the previous node
|
||||
|
||||
;:entry
|
||||
; lda _Sprites+SPRITE_ID,x
|
||||
; sta ObjectList+OL_SPRITE_ID,y
|
||||
; lda _Sprites+SPRITE_CLIP_TOP,x
|
||||
; sta ObjectList+OL_CLIP_TOP,y
|
||||
; lda _Sprites+SPRITE_CLIP_BOTTOM,x
|
||||
; sta ObjectList+OL_CLIP_BOTTOM,y
|
||||
|
||||
;:skip
|
||||
; lda _Sprites+SORTED_NEXT,x ; Advance to the next source item
|
||||
; tax
|
||||
; jsr _GetNextItem ; Get the first item from the list
|
||||
; cpx #EOL
|
||||
; bne :loop ; Exit if there are no valid entries
|
||||
|
||||
;:exit
|
||||
; lda #EOL ; End-of-list marker
|
||||
; sta ObjectList+OL_NEXT,y
|
||||
;:empty
|
||||
; rts
|
||||
|
||||
; Helper function to only return object from the sorted list if they are relevant for
|
||||
; display.
|
||||
_GetNextItem
|
||||
cpx #EOL ; early out if we're at the end of the list
|
||||
bne *+3
|
||||
rts
|
||||
|
||||
lda _Sprites+SPRITE_ID,x ; always return overlays
|
||||
bit #SPRITE_OVERLAY
|
||||
beq *+3
|
||||
rts
|
||||
|
||||
bit #SPRITE_HIDE ; skip hidden sprites
|
||||
bne :next
|
||||
lda _Sprites+IS_OFF_SCREEN,x ; skip off-screen sprites
|
||||
bne :next
|
||||
|
||||
rts ; found an object to return
|
||||
:next
|
||||
lda _Sprites+SORTED_NEXT,x
|
||||
tax
|
||||
bra _GetNextItem
|
||||
|
||||
DrawOverlayY
|
||||
phx
|
||||
phy
|
||||
|
||||
txy ; Swap X/Y
|
||||
plx
|
||||
phx
|
||||
jsr _DrawOverlay
|
||||
|
||||
ply
|
||||
plx
|
||||
rts
|
||||
|
||||
; A = top line
|
||||
; X = sprite record
|
||||
; Y = bottom line
|
||||
_DrawOverlay
|
||||
pha
|
||||
lda _Sprites+OVERLAY_PROC,x
|
||||
stal :disp+1
|
||||
lda _Sprites+OVERLAY_PROC+1,x
|
||||
stal :disp+2
|
||||
|
||||
lda ScreenY0 ; pass the address of the first line of the overlay
|
||||
clc
|
||||
adc _Sprites+OVERLAY_TOP,x
|
||||
asl
|
||||
tax
|
||||
lda ScreenAddr,x
|
||||
clc
|
||||
adc ScreenX0
|
||||
plx
|
||||
:disp jsl $000000
|
||||
rts
|
||||
|
||||
; Helper to set a palette index on a range of SCBs to help show which actions are applied to which lines
|
||||
DebugSCBs
|
||||
phx
|
||||
phy
|
||||
sep #$30 ; short m/x
|
||||
|
||||
pha ; save the SCB value
|
||||
|
||||
phx
|
||||
tya
|
||||
sec
|
||||
sbc 1,s
|
||||
tay ; number of scanlines
|
||||
|
||||
pla
|
||||
clc
|
||||
adc ScreenY0
|
||||
tax ; physical line index
|
||||
|
||||
pla
|
||||
:loop
|
||||
stal SHR_SCB,x
|
||||
inx
|
||||
dey
|
||||
bne :loop
|
||||
|
||||
rep #$30
|
||||
ply
|
||||
plx
|
||||
rts
|
||||
|
||||
|
||||
|
|
447
src/Sprite.s
447
src/Sprite.s
|
@ -150,7 +150,7 @@ ROW_BYTES equ 384 ; VBUFF_TILE_ROW_BYTES
|
|||
; a. If it is not marked in the DirtyTile list
|
||||
; * Clear its bit from the TileStore's TS_SPRITE_FLAG
|
||||
; * Add the tile to the DirtyTile list
|
||||
;t
|
||||
;
|
||||
; 2. If a sprite is marked as SPRITE_STATUS_REMOVED, then
|
||||
; A. Clear its bit from the SpriteBits bitmap
|
||||
; B. For each tile the sprite overlaps with:
|
||||
|
@ -223,10 +223,11 @@ _DoPhase1
|
|||
trb SpriteMap
|
||||
lda #SPRITE_STATUS_EMPTY ; Mark as empty so no error if we try to Add a sprite here again
|
||||
sta _Sprites+SPRITE_STATUS,y
|
||||
jmp _ClearSpriteFromTileStore ; Clear the tile flags, add to the dirty tile list and done
|
||||
|
||||
tyx
|
||||
jsr _DeleteSprite ; Remove sprite from linked list
|
||||
txy ; Restore y-register
|
||||
:hidden
|
||||
jmp _ClearSpriteFromTileStore
|
||||
jmp _ClearSpriteFromTileStore ; Clear the tile flags, add to the dirty tile list and done
|
||||
|
||||
:no_clear
|
||||
|
||||
|
@ -330,7 +331,7 @@ phase1 dw :phase1_0
|
|||
; the stamp every time. So this allows users to create stamps in advance and then
|
||||
; assign them to the sprites as needed.
|
||||
;
|
||||
; Note that the user had full freedom to create a stamp at any VBUFF address, however,
|
||||
; Note that the user has full freedom to create a stamp at any VBUFF address, however,
|
||||
; without leaving a buffer around each stamp, graphical corruption will occur. It is
|
||||
; recommended that the defines for VBUFF_SPRITE_START, VBUFF_TILE_ROW_BYTES and
|
||||
; VBUFF_TILE_COL_BYTES to calculate tile-aligned corner locations to lay out the
|
||||
|
@ -361,8 +362,8 @@ _CreateSpriteStamp
|
|||
; 01 - 8x16 (1x2 tiles)
|
||||
; 10 - 16x8 (2x1 tiles)
|
||||
; 11 - 16x16 (2x2 tiles)
|
||||
; Bit 13 : Show/Hid sprite
|
||||
; Bit 14 : Reserved. Must be zero.
|
||||
; Bit 13 : Show/Hide sprite during rendering
|
||||
; Bit 14 : Mark sprite as a compile sprite. SPRITE_DISP is treated as a compilation token.
|
||||
; Bit 15 : Reserved. Must be zero.
|
||||
; TBD: Bit 15 : Low Sprite priority. Draws behind high priority tiles.
|
||||
;
|
||||
|
@ -370,7 +371,7 @@ _CreateSpriteStamp
|
|||
; the vertical tiles are taken from tileId + 32. This is why tile sheets should be saved
|
||||
; with a width of 256 pixels.
|
||||
;
|
||||
; A = vbuffAddress
|
||||
; A = Sprite ID / Flags
|
||||
; Y = High Byte = x-pos, Low Byte = y-pos
|
||||
; X = Sprite Slot (0 - 15)
|
||||
_AddSprite
|
||||
|
@ -383,10 +384,11 @@ _AddSprite
|
|||
|
||||
sta _Sprites+SPRITE_ID,x ; Keep a copy of the full descriptor
|
||||
|
||||
lda #SPRITE_STATUS_ADDED
|
||||
lda #SPRITE_STATUS_ADDED ; Used to initialize the SPRITE_STATUS
|
||||
sta _Sprites+SPRITE_STATUS,x
|
||||
|
||||
stz _Sprites+VBUFF_ADDR,x ; Clear the VBUFF address, just to initialize it
|
||||
lda #$FFFF
|
||||
sta _Sprites+VBUFF_ADDR,x ; Clear the VBUFF address, just to initialize it
|
||||
|
||||
phy
|
||||
tya
|
||||
|
@ -397,8 +399,6 @@ _AddSprite
|
|||
and #$00FF
|
||||
sta _Sprites+SPRITE_X,x ; X coordinate
|
||||
|
||||
jsr _PrecalcAllSpriteInfo ; Cache sprite property values (simple stuff)
|
||||
|
||||
; Mark the dirty bit to indicate that the active sprite list needs to be rebuilt in the next
|
||||
; render call
|
||||
|
||||
|
@ -408,8 +408,292 @@ _AddSprite
|
|||
lda _SpriteBits,x ; Get the bit flag for this sprite slot
|
||||
tsb SpriteMap ; Mark it in the sprite map bit field
|
||||
|
||||
rts
|
||||
jsr _PrecalcSpriteSize ; Cache sprite property values
|
||||
jsr _PrecalcSpriteBounds
|
||||
|
||||
jsr _InsertSprite ; Insert it into the sorted list
|
||||
jmp _Validate
|
||||
|
||||
; _SortSprite
|
||||
;
|
||||
; Given a sprite's index, i, update the sprite permutation array such that p[j] = i where
|
||||
; the sprite is the j.th sprite ordered by the SPRITE_CLIP_TOP value. It is important to
|
||||
; note that the sorted sprite order does not impact rendering order (that is determined by
|
||||
; the sprite index position), but is only used to calculate region of the screen to update
|
||||
; and, in the future, may be useful for isometric perspectives where sorting order *is*
|
||||
; determined by y-position
|
||||
;
|
||||
; X = current sprite index
|
||||
;
|
||||
; The sorting strategy is to
|
||||
;
|
||||
; a) check if the current slot's y-pos is greater than the next item. If yes, then search forward
|
||||
; b) check if the current slot's y-pos is less than the prev item. If yes, then search in reverse
|
||||
; c) sprite is in the correct location
|
||||
;
|
||||
; The heuristic in play here is that, usually sprites will only move one position in the sorted order
|
||||
; between frames, if at all.
|
||||
_SortSprite
|
||||
lda _Sprites+SPRITE_CLIP_TOP,x
|
||||
|
||||
ldy _Sprites+SORTED_PREV,x
|
||||
bmi :chk_fwd
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,y
|
||||
bcc :scan_bkwd ; The current node needs to move to an lower position
|
||||
|
||||
:chk_fwd
|
||||
ldy _Sprites+SORTED_NEXT,x ; If there is nothing ahead of the current node, we're done
|
||||
bmi :early_out
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,y ; If the current node is <= the next node, we're done
|
||||
bcc :early_out
|
||||
bne :scan_fwd
|
||||
|
||||
:early_out
|
||||
rts
|
||||
|
||||
; Look to move the sprite into a later position
|
||||
:scan_fwd
|
||||
lda _Sprites+SORTED_NEXT,y ; Need to step forward; if we're at the end, then insert here
|
||||
bmi :insert_end
|
||||
tay
|
||||
lda _Sprites+SPRITE_CLIP_TOP,y ; Check against the next node. If it's less that current, keep going
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,x
|
||||
bcc :scan_fwd
|
||||
|
||||
; Put X before Y
|
||||
;
|
||||
; Change
|
||||
; a <=> x <=> b
|
||||
; c <=> y <=> d
|
||||
;
|
||||
; Into
|
||||
; a <=> b and c <=> x <=> y <=> d
|
||||
:insert_before
|
||||
jsr _ReleaseNode
|
||||
|
||||
tya
|
||||
sta _Sprites+SORTED_NEXT,x ; Link X to Y
|
||||
|
||||
lda _Sprites+SORTED_PREV,y
|
||||
sta _Sprites+SORTED_PREV,x ; Link X to C
|
||||
|
||||
txa ; Link Y to X
|
||||
sta _Sprites+SORTED_PREV,y
|
||||
|
||||
ldy _Sprites+SORTED_PREV,x ; Link C to X
|
||||
sta _Sprites+SORTED_NEXT,y
|
||||
rts
|
||||
|
||||
; Move X to the end of the list. Y point to the last element
|
||||
;
|
||||
; ; Change
|
||||
; a <=> x <=> b
|
||||
; y -> nil
|
||||
;
|
||||
; Into
|
||||
; a <=> b and y <=> x -> nil
|
||||
:insert_end
|
||||
jsr _ReleaseNode
|
||||
|
||||
lda #$FFFF
|
||||
sta _Sprites+SORTED_NEXT,x
|
||||
tya
|
||||
sta _Sprites+SORTED_PREV,x
|
||||
txa
|
||||
sta _Sprites+SORTED_NEXT,y
|
||||
rts
|
||||
|
||||
; Look to move the sprite into an earlier position
|
||||
:scan_bkwd
|
||||
lda _Sprites+SORTED_PREV,y ; Need to step backward; if we're at the beginning, then insert here
|
||||
bmi :insert_front
|
||||
tay
|
||||
lda _Sprites+SPRITE_CLIP_TOP,x ; Check against the next node. If it's less that current, keep going
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,y
|
||||
bcc :scan_bkwd
|
||||
|
||||
; Put X after Y
|
||||
;
|
||||
; Change
|
||||
; a <=> x <=> b
|
||||
; c <=> y <=> d
|
||||
;
|
||||
; Into
|
||||
; a <=> b and c <=> y <=> x <=> d
|
||||
:insert_after
|
||||
jsr _ReleaseNode
|
||||
|
||||
tya
|
||||
sta _Sprites+SORTED_PREV,x ; c <=> y <-- x --- d
|
||||
|
||||
lda _Sprites+SORTED_NEXT,y ; c <=> y <-- x --> d
|
||||
sta _Sprites+SORTED_NEXT,x
|
||||
|
||||
txa
|
||||
ldx _Sprites+SORTED_NEXT,y
|
||||
sta _Sprites+SORTED_NEXT,y ; c <=> y <=> x --> d
|
||||
|
||||
sta _Sprites+SORTED_PREV,x ; c <=> y <=> x <=> d
|
||||
rts
|
||||
|
||||
; Move X to the front of the list. Y points to the first element
|
||||
;
|
||||
; ; Change
|
||||
; a <=> x <=> b
|
||||
; head -> y
|
||||
;
|
||||
; Into
|
||||
; a <=> b and head -> x <=> y
|
||||
:insert_front
|
||||
jsr _ReleaseNode
|
||||
|
||||
stx _SortedHead
|
||||
txa
|
||||
sta _Sprites+SORTED_PREV,y
|
||||
lda #$FFFF
|
||||
sta _Sprites+SORTED_PREV,x
|
||||
tya
|
||||
sta _Sprites+SORTED_NEXT,x
|
||||
|
||||
:done
|
||||
rts
|
||||
|
||||
; Take the node pointed at X and remove it from the doubly-linked list.
|
||||
_ReleaseNode
|
||||
phy
|
||||
jsr _DeleteSprite
|
||||
ply
|
||||
rts
|
||||
|
||||
; Add a new sprite into the sorted double-linked list
|
||||
_InsertSprite
|
||||
lda _SortedHead ; If the list is empty, just insert the sprite index
|
||||
bmi :empty
|
||||
|
||||
tay ; Check the first item
|
||||
lda _Sprites+SPRITE_CLIP_TOP,x
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,y
|
||||
bcc :insert_head
|
||||
|
||||
:next
|
||||
lda _Sprites+SORTED_NEXT,y
|
||||
bmi :insert_tail
|
||||
|
||||
tay
|
||||
lda _Sprites+SPRITE_CLIP_TOP,x
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,y
|
||||
bcs :next
|
||||
|
||||
lda _Sprites+SORTED_PREV,y
|
||||
sta _Sprites+SORTED_PREV,x ; [p] <-- [c] [n]
|
||||
|
||||
tya
|
||||
sta _Sprites+SORTED_NEXT,x ; [p] <-- [c] --> [n]
|
||||
|
||||
txa
|
||||
ldx _Sprites+SORTED_PREV,y ; get ref to the [p]revious node
|
||||
sta _Sprites+SORTED_PREV,y ; [p] <-- [c] <=> [n]
|
||||
|
||||
sta _Sprites+SORTED_NEXT,x ; [p] <=> [c] <=> [n]
|
||||
|
||||
rts
|
||||
|
||||
:insert_head
|
||||
stx _SortedHead
|
||||
lda #$FFFF
|
||||
sta _Sprites+SORTED_PREV,x
|
||||
tya
|
||||
sta _Sprites+SORTED_NEXT,x
|
||||
txa
|
||||
sta _Sprites+SORTED_PREV,y
|
||||
rts
|
||||
|
||||
:insert_tail
|
||||
txa
|
||||
sta _Sprites+SORTED_NEXT,y
|
||||
tya
|
||||
sta _Sprites+SORTED_PREV,x
|
||||
lda #$FFFF
|
||||
sta _Sprites+SORTED_NEXT,x
|
||||
rts
|
||||
|
||||
:empty
|
||||
sta _Sprites+SORTED_NEXT,x
|
||||
sta _Sprites+SORTED_PREV,x
|
||||
stx _SortedHead
|
||||
rts
|
||||
|
||||
; Remove a sprite from the double-linked list
|
||||
_DeleteSprite
|
||||
ldy _Sprites+SORTED_NEXT,x
|
||||
bmi :remove_tail
|
||||
|
||||
cpx _SortedHead
|
||||
beq :remove_head
|
||||
|
||||
lda _Sprites+SORTED_PREV,x
|
||||
sta _Sprites+SORTED_PREV,y
|
||||
|
||||
tay
|
||||
lda _Sprites+SORTED_NEXT,x
|
||||
sta _Sprites+SORTED_NEXT,y
|
||||
rts
|
||||
|
||||
:remove_head
|
||||
sty _SortedHead
|
||||
lda #$FFFF
|
||||
sta _Sprites+SORTED_PREV,y
|
||||
rts
|
||||
|
||||
:remove_tail
|
||||
ldy _Sprites+SORTED_PREV,x
|
||||
bmi :make_empty
|
||||
|
||||
lda #$FFFF
|
||||
sta _Sprites+SORTED_NEXT,y
|
||||
rts
|
||||
|
||||
:make_empty
|
||||
lda #$FFFF
|
||||
sta _SortedHead
|
||||
rts
|
||||
|
||||
; Validate the integrity of the linked list
|
||||
_Validate
|
||||
:prev equ tmp0
|
||||
:curr equ tmp1
|
||||
|
||||
ldy #$FFFF
|
||||
ldx _SortedHead
|
||||
bmi :done
|
||||
:loop
|
||||
sty :prev
|
||||
stx :curr
|
||||
|
||||
lda _Sprites+SORTED_PREV,x
|
||||
cmp :prev
|
||||
beq *+4
|
||||
brk $08
|
||||
|
||||
cpy #$FFFF
|
||||
beq :skip
|
||||
lda _Sprites+SORTED_NEXT,y
|
||||
cmp :curr
|
||||
beq *+4
|
||||
brk $06
|
||||
|
||||
lda _Sprites+SPRITE_CLIP_TOP,x
|
||||
cmp _Sprites+SPRITE_CLIP_TOP,y
|
||||
bcs *+4
|
||||
brk $0A
|
||||
:skip
|
||||
txy
|
||||
lda _Sprites+SORTED_NEXT,x
|
||||
tax
|
||||
bpl :loop
|
||||
|
||||
:done
|
||||
rts
|
||||
; Macro to make the unrolled loop more concise
|
||||
;
|
||||
; 1. Load the tile store address from a fixed offset
|
||||
|
@ -643,25 +927,131 @@ _CacheSpriteBanks
|
|||
|
||||
rts
|
||||
|
||||
; Precalculate some cached values for a sprite. These are *only* to make other part of code,
|
||||
; Precalculate some cached values for a sprite. These are *only* to make other parts of code,
|
||||
; specifically the draw/erase routines more efficient.
|
||||
;
|
||||
; There are variations of this routine based on whether we are adding a new sprite, updating
|
||||
; it's tile information, or changing its position.
|
||||
;
|
||||
; X = sprite index
|
||||
_PrecalcAllSpriteInfo
|
||||
lda _Sprites+SPRITE_ID,x
|
||||
; and #$3E00
|
||||
_PrecalcSpriteVBuff
|
||||
lda _Sprites+SPRITE_ID,x ; Compiled sprites use the SPRITE_DISP as a fixed address to compiled code
|
||||
bit #SPRITE_COMPILED
|
||||
bne :compiled
|
||||
|
||||
xba
|
||||
and #$0006
|
||||
|
||||
tay
|
||||
lda _Sprites+VBUFF_ADDR,x
|
||||
clc
|
||||
adc _stamp_step,y
|
||||
sta _Sprites+SPRITE_DISP,x
|
||||
sta _Sprites+SPRITE_DISP,x ; Interpreted as an address in the VBUFF bank
|
||||
rts
|
||||
|
||||
:compiled
|
||||
xba
|
||||
and #$0006 ; Pick the address from the table of 4 values. Can use this value directly
|
||||
clc ; as an index
|
||||
adc _Sprites+VBUFF_ADDR,x
|
||||
tay
|
||||
lda [CompileBank0],y
|
||||
sta _Sprites+SPRITE_DISP,x ; Interpreted as an address in the CompileBank
|
||||
rts
|
||||
|
||||
; Compile the four stamps and keep a reference to the addresses. We take the current CompileBankTop address and allocate 8 bytes
|
||||
; of memory. Then compile each stamp and save the compilation address in the header area. Finally, the DISP_ADDR is set
|
||||
; to that value and the SPRITE_COMPILED bit is set in the SPRITE_ID word.
|
||||
;
|
||||
; A = sprite Id
|
||||
; X = vbuff base address
|
||||
_CompileStampSet
|
||||
:height equ tmp8
|
||||
:width equ tmp9
|
||||
:base equ tmp10
|
||||
:output equ tmp11
|
||||
:addrs equ tmp12 ; 4 words (tmp12, tmp13, tmp14 and tmp15)
|
||||
|
||||
; Save the base address
|
||||
stx :base
|
||||
|
||||
; Initialize the height and width based on the sprite flags
|
||||
|
||||
ldy #8
|
||||
sty :height
|
||||
ldx #4
|
||||
stx :width
|
||||
|
||||
bit #$1000 ; wide flag
|
||||
beq :skinny
|
||||
ldx #8
|
||||
stx :width
|
||||
:skinny
|
||||
|
||||
bit #$0800 ; tall flag
|
||||
beq :short
|
||||
ldy #16
|
||||
sty :height
|
||||
:short
|
||||
|
||||
lda CompileBankTop
|
||||
sta :output ; Save the current address as the return value
|
||||
|
||||
clc
|
||||
adc #8
|
||||
sta CompileBankTop ; Allocate space for the 4 addresses return by _CompileStamp
|
||||
|
||||
; ldy :height ; X and Y are already set for the first call
|
||||
; ldx :width
|
||||
lda :base
|
||||
jsr _CompileStamp ; Compile into the bank
|
||||
sta :addrs ; Save the address temporarily
|
||||
|
||||
ldy :height
|
||||
ldx :width
|
||||
clc
|
||||
lda :base
|
||||
adc _stamp_step+2
|
||||
jsr _CompileStamp
|
||||
sta :addrs+2
|
||||
|
||||
ldy :height
|
||||
ldx :width
|
||||
clc
|
||||
lda :base
|
||||
adc _stamp_step+4
|
||||
jsr _CompileStamp
|
||||
sta :addrs+4
|
||||
|
||||
ldy :height
|
||||
ldx :width
|
||||
clc
|
||||
lda :base
|
||||
adc _stamp_step+6
|
||||
jsr _CompileStamp
|
||||
sta :addrs+6
|
||||
|
||||
; Now the sprite stamps are all compiled. Set the bank to the compilation bank and fill in the header
|
||||
|
||||
phb
|
||||
|
||||
ldy :output
|
||||
pei CompileBank
|
||||
plb
|
||||
|
||||
lda :addrs
|
||||
sta: 0,y
|
||||
lda :addrs+2
|
||||
sta: 2,y
|
||||
lda :addrs+4
|
||||
sta: 4,y
|
||||
lda :addrs+6
|
||||
sta: 6,y
|
||||
|
||||
plb
|
||||
plb
|
||||
|
||||
tya ; Put the output value into the accumulator
|
||||
clc ; No error
|
||||
rts
|
||||
|
||||
_PrecalcSpriteSize
|
||||
; Set the sprite's width and height
|
||||
lda #4
|
||||
sta _Sprites+SPRITE_WIDTH,x
|
||||
|
@ -681,10 +1071,11 @@ _PrecalcAllSpriteInfo
|
|||
lda #16
|
||||
sta _Sprites+SPRITE_HEIGHT,x
|
||||
:height_8
|
||||
rts
|
||||
|
||||
; Clip the sprite's bounding box to the play field size and also set a flag if the sprite
|
||||
; is fully off-screen or not
|
||||
|
||||
_PrecalcSpriteBounds
|
||||
lda _Sprites+SPRITE_X,x
|
||||
bpl :pos_x
|
||||
lda #0
|
||||
|
@ -760,14 +1151,14 @@ _RemoveSprite
|
|||
ora #SPRITE_STATUS_REMOVED
|
||||
sta _Sprites+SPRITE_STATUS,x
|
||||
|
||||
rts
|
||||
rts ; The _DeleteSprite call is made in _DoPhase1 during the next render
|
||||
|
||||
; Update the sprite's flags. We do not allow the size of a sprite to be changed. That requires
|
||||
; the sprite to be removed and re-added.
|
||||
;
|
||||
; A = Sprite slot
|
||||
; X = New Sprite Flags
|
||||
; Y = New Sprite Stamp Address
|
||||
; Y = New Sprite Stamp Address | New Compiled Sprite Token
|
||||
_UpdateSprite
|
||||
cmp #MAX_SPRITES
|
||||
bcc :ok
|
||||
|
@ -813,7 +1204,7 @@ _UpdateSprite
|
|||
ora #SPRITE_STATUS_UPDATED
|
||||
sta _Sprites+SPRITE_STATUS,x
|
||||
|
||||
jmp _PrecalcAllSpriteInfo ; Cache stuff and return
|
||||
jmp _PrecalcSpriteVBuff ; Cache stuff and return
|
||||
|
||||
; Move a sprite to a new location. If the tile ID of the sprite needs to be changed, then
|
||||
; a full remove/add cycle needs to happen
|
||||
|
@ -849,4 +1240,6 @@ _MoveSprite
|
|||
ora #SPRITE_STATUS_MOVED
|
||||
sta _Sprites+SPRITE_STATUS,x
|
||||
|
||||
jmp _PrecalcAllSpriteInfo ; Can be specialized to only update (x,y) values
|
||||
jsr _PrecalcSpriteBounds ; Can be specialized to only update (x,y) values
|
||||
jsr _SortSprite ; Update the sprite's sorted position
|
||||
jmp _Validate
|
||||
|
|
|
@ -186,6 +186,7 @@ _CalcDirtySprite
|
|||
eor #$FFFF ; A = -X - 1
|
||||
sec ; C = 1
|
||||
adc _Sprites+SPRITE_DISP,y ; A = SPRITE_DISP + (-X - 1) + 1 = SPRITE_DISP - X
|
||||
dec ; [!! INTERLOCK !!] pre-decrement to save clc in core blitter. See dobit macros in src/Tiles.s
|
||||
sta _Sprites+TS_VBUFF_BASE,y
|
||||
|
||||
; Create an offset value for loading the calculated VBUFF addresses within the core renderer by
|
||||
|
|
|
@ -1,3 +1,282 @@
|
|||
; Compile a stamp into a compilation cache
|
||||
;
|
||||
; A = vbuff address
|
||||
; X = width (in bytes)
|
||||
; Y = height (in scanlines)
|
||||
|
||||
_CompileStamp
|
||||
:lines equ tmp0
|
||||
:sprwidth equ tmp1
|
||||
:cntwidth equ tmp2
|
||||
:baseAddr equ tmp3
|
||||
:destAddr equ tmp4
|
||||
:vbuffAddr equ tmp5
|
||||
:rtnval equ tmp6
|
||||
|
||||
LDA_IMM_OPCODE equ $A9
|
||||
LDA_ABS_X_OPCODE equ $BD
|
||||
AND_IMM_OPCODE equ $29
|
||||
ORA_IMM_OPCODE equ $09
|
||||
STA_ABS_X_OPCODE equ $9D
|
||||
STZ_ABS_X_OPCODE equ $9E
|
||||
RTL_OPCODE equ $6B
|
||||
|
||||
sta :vbuffAddr
|
||||
sty :lines
|
||||
txa
|
||||
lsr
|
||||
sta :sprwidth
|
||||
|
||||
; Get ready to build the sprite
|
||||
|
||||
ldy CompileBankTop ; First free byte in the compilation bank
|
||||
sty :rtnval ; Save it as the return value
|
||||
|
||||
phb
|
||||
pei CompileBank
|
||||
plb ; Set the bank to the compilation cache
|
||||
|
||||
stz :baseAddr
|
||||
stz :destAddr
|
||||
|
||||
:oloop
|
||||
lda :sprwidth
|
||||
sta :cntwidth
|
||||
ldx :vbuffAddr
|
||||
|
||||
:iloop
|
||||
ldal spritemask,x
|
||||
beq :no_mask ; If Mask == $0000, then it's a solid word
|
||||
cmp #$FFFF
|
||||
beq :next ; If Mask == $FFFF, then it's transparent
|
||||
|
||||
; Mask with the screen data
|
||||
lda #LDA_ABS_X_OPCODE
|
||||
sta: 0,y
|
||||
lda :destAddr
|
||||
sta: 1,y
|
||||
lda #AND_IMM_OPCODE
|
||||
sta: 3,y
|
||||
ldal spritemask,x
|
||||
sta: 4,y
|
||||
lda #ORA_IMM_OPCODE
|
||||
sta: 6,y
|
||||
ldal spritedata,x
|
||||
sta: 7,y
|
||||
lda #STA_ABS_X_OPCODE
|
||||
sta: 9,y
|
||||
lda :destAddr
|
||||
sta: 10,y
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #12
|
||||
tay
|
||||
bra :next
|
||||
|
||||
; Just store the data
|
||||
:no_mask lda #LDA_IMM_OPCODE
|
||||
sta: 0,y
|
||||
ldal spritedata,x
|
||||
beq :zero
|
||||
sta: 1,y
|
||||
|
||||
lda #STA_ABS_X_OPCODE
|
||||
sta: 3,y
|
||||
lda :destAddr
|
||||
sta: 4,y
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #6
|
||||
tay
|
||||
bra :next
|
||||
|
||||
:zero lda #STZ_ABS_X_OPCODE
|
||||
sta: 0,y
|
||||
lda :destAddr
|
||||
sta: 1,y
|
||||
|
||||
iny
|
||||
iny
|
||||
iny
|
||||
|
||||
:next
|
||||
inx
|
||||
inx
|
||||
|
||||
inc :destAddr ; Move to the next word
|
||||
inc :destAddr
|
||||
|
||||
dec :cntwidth
|
||||
bne :iloop
|
||||
|
||||
lda :vbuffAddr
|
||||
clc
|
||||
adc #SPRITE_PLANE_SPAN
|
||||
sta :vbuffAddr
|
||||
|
||||
lda :baseAddr ; Move to the next line
|
||||
clc
|
||||
adc #160
|
||||
sta :baseAddr
|
||||
sta :destAddr
|
||||
|
||||
dec :lines
|
||||
beq :out
|
||||
brl :oloop
|
||||
|
||||
:out
|
||||
lda #RTL_OPCODE ; Finish up the subroutine
|
||||
sta: 0,y
|
||||
iny
|
||||
sty CompileBankTop
|
||||
|
||||
plb
|
||||
plb
|
||||
lda :rtnval ; Address in the compile memory
|
||||
rts
|
||||
|
||||
; Draw a sprite directly to the graphics screen. If sprite is clipped at all, do not draw.
|
||||
;
|
||||
; X = sprite record index
|
||||
_DSTSOut
|
||||
rts
|
||||
|
||||
_DrawStampToScreen
|
||||
lda _Sprites+IS_OFF_SCREEN,x ; If the sprite is off-screen, don't draw it
|
||||
bne _DSTSOut
|
||||
|
||||
lda _Sprites+SPRITE_ID,x ; If the sprite is hidden or an overlay, don't draw it
|
||||
bit #SPRITE_OVERLAY+SPRITE_HIDE
|
||||
bne _DSTSOut
|
||||
|
||||
lda _Sprites+SPRITE_CLIP_WIDTH,x ; If the sprite is clipped to the playfield, don't draw it
|
||||
cmp _Sprites+SPRITE_WIDTH,x
|
||||
bne _DSTSOut
|
||||
lda _Sprites+SPRITE_CLIP_HEIGHT,x
|
||||
cmp _Sprites+SPRITE_HEIGHT,x
|
||||
bne _DSTSOut
|
||||
|
||||
clc
|
||||
lda _Sprites+SPRITE_Y,x
|
||||
adc ScreenY0
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta tmp0
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc tmp0
|
||||
clc
|
||||
adc #$2000
|
||||
clc
|
||||
adc ScreenX0
|
||||
adc _Sprites+SPRITE_X,x ; Move to the horizontal address
|
||||
tay ; This is the on-screen address
|
||||
|
||||
lda _Sprites+SPRITE_ID,x ; If this is a compiled sprite, call the routine in the compilation bank
|
||||
bit #SPRITE_COMPILED
|
||||
beq *+5
|
||||
brl :compiled
|
||||
|
||||
lda _Sprites+SPRITE_HEIGHT,x
|
||||
sta tmp0
|
||||
|
||||
; Sprite is either 8 or 16 pixels wide, so select the entry point
|
||||
lda _Sprites+SPRITE_WIDTH,x
|
||||
cmp #4
|
||||
beq :skinny
|
||||
|
||||
lda _Sprites+SPRITE_DISP,x ; This is the VBUFF address with the correct sprite frame
|
||||
tax
|
||||
phb
|
||||
pea $0101
|
||||
plb
|
||||
plb
|
||||
bra :entry16
|
||||
:loop16
|
||||
clc
|
||||
txa
|
||||
adc #SPRITE_PLANE_SPAN
|
||||
tax
|
||||
tya
|
||||
adc #SHR_LINE_WIDTH
|
||||
tay
|
||||
:entry16
|
||||
lda: 6,y
|
||||
andl spritemask+6,x
|
||||
oral spritedata+6,x
|
||||
sta: 6,y
|
||||
lda: 4,y
|
||||
andl spritemask+4,x
|
||||
oral spritedata+4,x
|
||||
sta: 4,y
|
||||
lda: 2,y
|
||||
andl spritemask+2,x
|
||||
oral spritedata+2,x
|
||||
sta: 2,y
|
||||
lda: 0,y
|
||||
andl spritemask+0,x
|
||||
oral spritedata+0,x
|
||||
sta: 0,y
|
||||
|
||||
dec tmp0
|
||||
bne :loop16
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
:skinny
|
||||
lda _Sprites+SPRITE_DISP,x ; This is the VBUFF address with the correct sprite frame
|
||||
tax
|
||||
phb
|
||||
pea $0101
|
||||
plb
|
||||
plb
|
||||
bra :entry8
|
||||
:loop8
|
||||
clc
|
||||
txa
|
||||
adc #SPRITE_PLANE_SPAN
|
||||
tax
|
||||
tya
|
||||
adc #SHR_LINE_WIDTH
|
||||
tay
|
||||
:entry8
|
||||
lda: 2,y
|
||||
andl spritemask+2,x
|
||||
oral spritedata+2,x
|
||||
sta: 2,y
|
||||
lda: 0,y
|
||||
andl spritemask+0,x
|
||||
oral spritedata+0,x
|
||||
sta: 0,y
|
||||
|
||||
dec tmp0
|
||||
bne :loop8
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
:compiled
|
||||
lda CompileBank-1 ; Load the bank into the high byte
|
||||
stal :patch+2 ; Put it into the 3rd address bytes (2nd byte is garbage)
|
||||
lda _Sprites+SPRITE_DISP,x ; Address in the compile bank
|
||||
stal :patch+1 ; Set 1st and 2nd address bytes
|
||||
|
||||
tyx ; Put on-screen address in X-register
|
||||
phb ; Compiled sprites assume bank register is $01
|
||||
pea $0101
|
||||
plb
|
||||
plb
|
||||
:patch jsl $000000 ; Dispatch
|
||||
plb
|
||||
rts
|
||||
|
||||
; Alternate entry point that takes arguments in registers instead of using a _Sprite
|
||||
; record
|
||||
;
|
||||
|
|
226
src/SpriteV1.s
226
src/SpriteV1.s
|
@ -1,226 +0,0 @@
|
|||
; Old code the was in Version 1, but is not needed. May be adapted for Verions 2.
|
||||
|
||||
; Y = _Sprites array offset
|
||||
_EraseSpriteY
|
||||
lda _Sprites+OLD_VBUFF_ADDR,y
|
||||
beq :noerase
|
||||
ldx _Sprites+SPRITE_DISP,y ; get the dispatch index for this sprite (32 values)
|
||||
jmp (:do_erase,x)
|
||||
:noerase rts
|
||||
:do_erase dw _EraseTileSprite8x8,_EraseTileSprite8x8,_EraseTileSprite8x8,_EraseTileSprite8x8
|
||||
dw _EraseTileSprite8x16,_EraseTileSprite8x16,_EraseTileSprite8x16,_EraseTileSprite8x16
|
||||
dw _EraseTileSprite16x8,_EraseTileSprite16x8,_EraseTileSprite16x8,_EraseTileSprite16x8
|
||||
dw _EraseTileSprite16x16,_EraseTileSprite16x16,_EraseTileSprite16x16,_EraseTileSprite16x16
|
||||
dw _EraseTileSprite8x8,_EraseTileSprite8x8,_EraseTileSprite8x8,_EraseTileSprite8x8
|
||||
dw _EraseTileSprite8x16,_EraseTileSprite8x16,_EraseTileSprite8x16,_EraseTileSprite8x16
|
||||
dw _EraseTileSprite16x8,_EraseTileSprite16x8,_EraseTileSprite16x8,_EraseTileSprite16x8
|
||||
dw _EraseTileSprite16x16,_EraseTileSprite16x16,_EraseTileSprite16x16,_EraseTileSprite16x16
|
||||
|
||||
; A = bank address
|
||||
_EraseTileSprite8x8
|
||||
tax
|
||||
phb ; Save the bank to switch to the sprite plane
|
||||
|
||||
pei SpriteBanks
|
||||
plb ; pop the data bank (low byte)
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb ; pop the mask bank (high byte)
|
||||
lda #$FFFF
|
||||
]line equ 0
|
||||
lup 8
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
_EraseTileSprite8x16
|
||||
tax
|
||||
phb ; Save the bank to switch to the sprite plane
|
||||
|
||||
pei SpriteBanks
|
||||
plb ; pop the data bank (low byte)
|
||||
|
||||
]line equ 0
|
||||
lup 16
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb ; pop the mask bank (high byte)
|
||||
lda #$FFFF
|
||||
]line equ 0
|
||||
lup 16
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
_EraseTileSprite16x8
|
||||
tax
|
||||
phb ; Save the bank to switch to the sprite plane
|
||||
|
||||
pei SpriteBanks
|
||||
plb ; pop the data bank (low byte)
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+4,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+6,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb ; pop the mask bank (high byte)
|
||||
lda #$FFFF
|
||||
]line equ 0
|
||||
lup 8
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+4,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+6,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
_EraseTileSprite16x16
|
||||
tax
|
||||
phb ; Save the bank to switch to the sprite plane
|
||||
|
||||
pei SpriteBanks
|
||||
plb ; pop the data bank (low byte)
|
||||
|
||||
]line equ 0
|
||||
lup 16
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+4,x
|
||||
stz: {]line*SPRITE_PLANE_SPAN}+6,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb ; pop the mask bank (high byte)
|
||||
|
||||
lda #$FFFF
|
||||
]line equ 0
|
||||
lup 16
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+0,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+4,x
|
||||
sta: {]line*SPRITE_PLANE_SPAN}+6,x
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
|
||||
; First, if there is only one sprite, then we can skip any overhead and do a single lda/and/ora/sta to put the
|
||||
; sprite data on the screen.
|
||||
;
|
||||
; Second, if there are 4 or less, then we "stack" the sprite data using an unrolled loop that allows each
|
||||
; sprite to just be a single and/ora pair and the final result is not written to any intermediate memory buffer.
|
||||
;
|
||||
; Third, if there are 5 or more sprites, then we assume that the sprites are "dense" and that there will be a
|
||||
; non-trivial amount of overdraw. In this case we do a series of optimized copies of the sprite data *and*
|
||||
; masks into a direct page buffer in *reverse order*. Once a mask value becomes zero, then nothing else can
|
||||
; show through and that value can be skipped. Once all of the mask values are zero, then the render is terminated
|
||||
; and the data buffer copied to the final destination.
|
||||
;
|
||||
; Note that these rendering algorithms impose a priority ordering on the sprites where lower sprite IDs are drawn
|
||||
; underneath higher sprite IDs.
|
||||
RenderActiveSpriteTiles
|
||||
cmp #0 ; Is there only one active sprite? If so optimise
|
||||
bne :many
|
||||
|
||||
ldx vbuff ; load the address to the (adjusted) sprite tile
|
||||
lda TileStore+TS_SCREEN_ADDR,y
|
||||
tay
|
||||
|
||||
lda tiledata+0,y
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
sta 00,s
|
||||
|
||||
lda tiledata+2,y
|
||||
andl spritemask+2,x
|
||||
oral spritedata+2,x
|
||||
sta 02,s
|
||||
|
||||
...
|
||||
tsc
|
||||
adc #320
|
||||
tcs
|
||||
...
|
||||
|
||||
lda tiledata+{line*4},y
|
||||
andl spritemask+{line*SPAN},x
|
||||
oral spritedata+{line*SPAN},x
|
||||
sta 160,s
|
||||
|
||||
lda tiledata+{line*4}+2,y
|
||||
andl spritemask+{line*SPAN}+2,x
|
||||
oral spritedata+{line*SPAN}+2,x
|
||||
sta 162,s
|
||||
|
||||
rts
|
||||
|
||||
|
||||
:many
|
||||
lda TileStore+TS_SCREEN_ADDR,y
|
||||
tcs
|
||||
lda TileStore+TS_TILE_ADDR,y
|
||||
tay
|
||||
|
||||
ldx count
|
||||
jmp (:arr,x)
|
||||
lda tiledata+0,y
|
||||
ldx vbuff
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
ldx vbuff+2
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
ldx vbuff+4
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
...
|
||||
sta 00,s
|
||||
|
||||
ldx count
|
||||
jmp (:arr,x)
|
||||
lda tiledata+0,y
|
||||
ldx vbuff
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
ldx vbuff+2
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
ldx vbuff+4
|
||||
andl spritemask,x
|
||||
oral spritedata,x
|
||||
...
|
||||
sta 02,s
|
||||
|
||||
sta 160,s
|
||||
|
||||
sta 162,s
|
||||
|
||||
tsc
|
||||
adc #320
|
113
src/Tiles.s
113
src/Tiles.s
|
@ -1,20 +1,29 @@
|
|||
; Basic tile functions
|
||||
|
||||
; Copy tileset data from a pointer in memory to the tiledata back
|
||||
; X = high word
|
||||
; A = low word
|
||||
;
|
||||
; tmp0 = Pointer to tile data
|
||||
; X = first tile
|
||||
; Y = last tile
|
||||
;
|
||||
; To copy in four tiles starting at tile 5, for example, X = 5 and Y = 9
|
||||
_LoadTileSet
|
||||
sta tmp0
|
||||
stx tmp1
|
||||
txa
|
||||
_Mul128 ; Jump to the target location
|
||||
tax
|
||||
tya
|
||||
_Mul128
|
||||
sta tmp2 ; This is the terminating byte
|
||||
|
||||
ldy #0
|
||||
tyx
|
||||
:loop lda [tmp0],y
|
||||
stal tiledata,x
|
||||
dex
|
||||
dex
|
||||
dey
|
||||
dey
|
||||
bne :loop
|
||||
inx
|
||||
inx
|
||||
iny
|
||||
iny
|
||||
cpx tmp2
|
||||
bne :loop ; Use BNE so when Y=512 => $0000, we wait for wrap-around
|
||||
rts
|
||||
|
||||
|
||||
|
@ -259,7 +268,7 @@ _SetNormalTileProcs
|
|||
brl :pickDynProc
|
||||
|
||||
:pickTwoLyrProc ldy #TwoLyrProcs
|
||||
pla ; pull of the proc index
|
||||
pla ; pull off the proc index
|
||||
jmp _SetTileProcs
|
||||
|
||||
; Specialized check for when the engine is in "Fast" mode. If is a simple decision tree based on whether
|
||||
|
@ -365,6 +374,12 @@ _SetTile
|
|||
:changed sta oldTileId
|
||||
lda newTileId
|
||||
sta TileStore+TS_TILE_ID,x ; Value is different, store it.
|
||||
|
||||
; If the user bit is set, then skip most of the setup and just fill in the TileProcs with the user callback
|
||||
; target
|
||||
bit #TILE_USER_BIT
|
||||
bne :set_user_tile
|
||||
|
||||
jsr _GetTileAddr
|
||||
sta TileStore+TS_TILE_ADDR,x ; Committed to drawing this tile, so get the address of the tile in the tiledata bank for later
|
||||
|
||||
|
@ -388,27 +403,47 @@ _SetTile
|
|||
jsr _SetNormalTileProcs
|
||||
jmp _PushDirtyTileX
|
||||
|
||||
:set_user_tile
|
||||
lda #UserTileDispatch
|
||||
stal K_TS_BASE_TILE_DISP,x
|
||||
lda #UserTileDispatch
|
||||
stal K_TS_SPRITE_TILE_DISP,x
|
||||
lda #UserTileDispatch
|
||||
stal K_TS_ONE_SPRITE,x
|
||||
jmp _PushDirtyTileX
|
||||
|
||||
; Trampoline / Dispatch table for user-defined tiles. If the user calls the GTESetCustomTileCallback toolbox routine,
|
||||
; then this value is patched out. Calling GTESetCustomTileCallback with NULL will disconnect the user's routine.
|
||||
UserTileDispatch
|
||||
ldal TileStore+TS_TILE_ID,x ; Replace the tile data address (unset) with the tile id
|
||||
_UTDPatch jsl UserHook1 ; Call the users code
|
||||
plb ; Restore the data bank
|
||||
rts
|
||||
|
||||
; Stub to have a valid address for initialization / reset
|
||||
UserHook1 rtl
|
||||
|
||||
; X = Tile Store offset
|
||||
; Y = Engine Mode Base Table address
|
||||
; A = Table proc index
|
||||
;
|
||||
; see TileProcTables in static/TileStore.s
|
||||
tblPtr equ blttmp
|
||||
_SetTileProcs
|
||||
:tblPtr equ blttmp
|
||||
|
||||
; Multiple the proc index by 6 to get the correct table entry offset
|
||||
|
||||
asl
|
||||
sta tblPtr
|
||||
sta :tblPtr
|
||||
asl
|
||||
adc tblPtr
|
||||
sta tblPtr
|
||||
adc :tblPtr
|
||||
sta :tblPtr
|
||||
|
||||
; Add this offset to the base table address
|
||||
|
||||
tya
|
||||
adc tblPtr
|
||||
sta tblPtr
|
||||
adc :tblPtr
|
||||
sta :tblPtr
|
||||
|
||||
; Set the pointer to this bank
|
||||
|
||||
|
@ -416,36 +451,36 @@ _SetTileProcs
|
|||
phk
|
||||
pla
|
||||
and #$00FF
|
||||
sta tblPtr+2
|
||||
sta :tblPtr+2
|
||||
|
||||
; Lookup the tile procedures
|
||||
|
||||
ldy #0
|
||||
lda [tblPtr],y
|
||||
lda [:tblPtr],y
|
||||
stal K_TS_BASE_TILE_DISP,x
|
||||
|
||||
ldy #2
|
||||
lda [tblPtr],y
|
||||
lda [:tblPtr],y
|
||||
stal K_TS_SPRITE_TILE_DISP,x
|
||||
|
||||
ldy #4
|
||||
lda [tblPtr],y
|
||||
lda [:tblPtr],y
|
||||
stal K_TS_ONE_SPRITE,x
|
||||
rts
|
||||
|
||||
; TileProcTables
|
||||
;
|
||||
; Tables of tuples used to populate the K_TS_* dispatch arrays for different combinations. This is
|
||||
; easier to maintain than a bunch of conditional code. Each etry hold three addresses.
|
||||
; easier to maintain than a bunch of conditional code. Each entry holds three addresses.
|
||||
;
|
||||
; First address: Draw a tile directly into the code buffer (no sprites)
|
||||
; Second address: Draw a tile merged with sprite data from the direct page
|
||||
; Third address: Specialize routine to draw a tile merged with one sprite
|
||||
;
|
||||
; There are unique tuples of routines for all of the different combinations of tile properties
|
||||
; and engine modes. This is an extesive number of combinations, but it simplified the development
|
||||
; and maintainence of the rendering subroutines. Also, the difference subroutines can be written
|
||||
; in any way and can make use of their on subroutines to reduce code size.
|
||||
; and engine modes. This is an extensive number of combinations, but it simplifies the development
|
||||
; and maintainence of the rendering subroutines. Also, the different subroutines can be written
|
||||
; in any way and can make use of their own subroutines to reduce code size.
|
||||
;
|
||||
; Properties:
|
||||
;
|
||||
|
@ -497,6 +532,12 @@ DynUnder dw CopyDynamicTile,DynamicUnder,OneSpriteDynamicUnder
|
|||
; the TILE_SOLID_BIT hint bit can be set to indicate that a tile
|
||||
; has no transparency. This allows one of the faster routines
|
||||
; to be selected from the other Proc tables
|
||||
;
|
||||
; FUTURE: An optimization that can be done is to have the snippets
|
||||
; code layout fixed based on the EngineFlags and then the Two Layer
|
||||
; routines should only need to update the DATA and MASK operands in
|
||||
; the snippet at a fixed location rather than rebuild the ~20 bytes
|
||||
; of data.
|
||||
TwoLyrProcs
|
||||
TwoLyrOverZA dw Tile0TwoLyr,SpriteOver0TwoLyr,OneSpriteOver0TwoLyr
|
||||
TwoLyrOverZV dw Tile0TwoLyr,SpriteOver0TwoLyr,OneSpriteOver0TwoLyr
|
||||
|
@ -571,14 +612,14 @@ dobit mac
|
|||
bcc next_bit
|
||||
beq last_bit
|
||||
tax
|
||||
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
lda (SPRITE_VBUFF_PTR+{]1*2}),y ; The carry is always set
|
||||
; clc
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2} ; [!! INTERLOCK !!] The table is pre-decremented in Sprite2.s
|
||||
sta sprite_ptr0+{]2*4}
|
||||
txa
|
||||
jmp ]3
|
||||
last_bit lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc ; pre-adjust these later
|
||||
; clc ; pre-adjust these later
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
sta sprite_ptr0+{]2*4}
|
||||
jmp ]4
|
||||
|
@ -593,13 +634,13 @@ dobit1 mac
|
|||
beq last_bit
|
||||
tax
|
||||
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc
|
||||
; clc
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
sta sprite_ptr0+{]2*4}
|
||||
txa
|
||||
jmp ]3
|
||||
last_bit lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc ; pre-adjust these later
|
||||
; clc ; pre-adjust these later
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
sta sprite_ptr0+{]2*4}
|
||||
tyx
|
||||
|
@ -612,7 +653,7 @@ stpbit mac
|
|||
lsr
|
||||
bcc next_bit
|
||||
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc ; pre-adjust these later
|
||||
; clc ; pre-adjust these later
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
sta sprite_ptr0+{]2*4}
|
||||
jmp ]3
|
||||
|
@ -622,7 +663,7 @@ next_bit
|
|||
; Last bit test which *must* be set
|
||||
endbit mac
|
||||
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc ; pre-adjust these later
|
||||
; clc ; pre-adjust these later
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
sta sprite_ptr0+{]2*4}
|
||||
jmp ]3
|
||||
|
@ -630,7 +671,7 @@ endbit mac
|
|||
|
||||
endbit1 mac
|
||||
lda (SPRITE_VBUFF_PTR+{]1*2}),y
|
||||
clc ; pre-adjust these later
|
||||
; clc ; pre-adjust these later
|
||||
adc _Sprites+TS_VBUFF_BASE+{]1*2}
|
||||
sta sprite_ptr0+{]2*4}
|
||||
tyx
|
||||
|
@ -730,7 +771,7 @@ b_15_3 endbit 15;3;]4
|
|||
; Store some tables in the K bank that will be used exclusively for jmp (abs,x) dispatch
|
||||
|
||||
K_TS_BASE_TILE_DISP ds TILE_STORE_SIZE ; draw the tile without a sprite
|
||||
K_TS_COPY_TILE_DATA ds TILE_STORE_SIZE ; copy/merge the tile into temp storage
|
||||
;K_TS_COPY_TILE_DATA ds TILE_STORE_SIZE ; copy/merge the tile into temp storage
|
||||
K_TS_SPRITE_TILE_DISP ds TILE_STORE_SIZE ; select the sprite routine for this tile
|
||||
K_TS_ONE_SPRITE ds TILE_STORE_SIZE ; specialized sprite routine when only one sprite covers the tile
|
||||
K_TS_APPLY_TILE_DATA ds TILE_STORE_SIZE ; move tile from temp storage into code field
|
||||
;K_TS_APPLY_TILE_DATA ds TILE_STORE_SIZE ; move tile from temp storage into code field
|
257
src/Tool.s
257
src/Tool.s
|
@ -96,6 +96,12 @@ _CallTable
|
|||
|
||||
adrl _TSClearBG1Buffer-1
|
||||
adrl _TSSetBG1Scale-1
|
||||
adrl _TSGetAddress-1
|
||||
|
||||
adrl _TSCompileSpriteStamp-1
|
||||
adrl _TSSetAddress-1
|
||||
adrl _TSUpdateOverlay-1
|
||||
|
||||
_CTEnd
|
||||
_GTEAddSprite MAC
|
||||
UserTool $1000+GTEToolNum
|
||||
|
@ -156,7 +162,9 @@ zpToUse = userId+4
|
|||
|
||||
; SetWAP(userOrSystem, tsNum, waptPtr)
|
||||
|
||||
pea #$8000 ; $8000 = user tool set
|
||||
lda EngineMode ; $0000 = system tool, $8000 = user tool set
|
||||
and #$8000
|
||||
pha
|
||||
pei ToolNum ; Push the tool number from the direct page
|
||||
pea $0000 ; High word of WAP is zero (bank 0)
|
||||
phd ; Low word of WAP is the direct page
|
||||
|
@ -181,7 +189,9 @@ _TSShutDown
|
|||
jsr _CoreShutDown ; Shut down the library
|
||||
plb
|
||||
|
||||
pea $8000
|
||||
lda EngineMode ; $0000 = system tool, $8000 = user tool set
|
||||
and #$8000
|
||||
pha
|
||||
pei ToolNum
|
||||
pea $0000 ; Set WAP to null
|
||||
pea $0000
|
||||
|
@ -227,14 +237,14 @@ _TSReserved
|
|||
|
||||
; SetScreenMode(width, height)
|
||||
_TSSetScreenMode
|
||||
height equ FirstParam
|
||||
width equ FirstParam+2
|
||||
:height equ FirstParam
|
||||
:width equ FirstParam+2
|
||||
|
||||
_TSEntry
|
||||
|
||||
lda height,s
|
||||
lda :height,s
|
||||
tay
|
||||
lda width,s
|
||||
lda :width,s
|
||||
tax
|
||||
jsr _SetScreenMode
|
||||
|
||||
|
@ -288,7 +298,21 @@ _TSRender
|
|||
|
||||
_TSEntry
|
||||
lda :flags,s
|
||||
bit #RENDER_WITH_SHADOWING
|
||||
beq :no_shadowing
|
||||
jsr _RenderWithShadowing
|
||||
bra :done
|
||||
|
||||
:no_shadowing
|
||||
bit #RENDER_PER_SCANLINE
|
||||
beq :no_scanline
|
||||
jsr _RenderScanlines
|
||||
bra :done
|
||||
|
||||
:no_scanline
|
||||
jsr _Render
|
||||
|
||||
:done
|
||||
_TSExit #0;#2
|
||||
|
||||
|
||||
|
@ -301,20 +325,29 @@ _TSRenderDirty
|
|||
jsr _RenderDirty
|
||||
_TSExit #0;#2
|
||||
|
||||
; LoadTileSet(Pointer)
|
||||
; LoadTileSet(Start, Finish, Pointer)
|
||||
_TSLoadTileSet
|
||||
TSPtr equ FirstParam
|
||||
:TSPtr equ FirstParam
|
||||
:finish equ FirstParam+4
|
||||
:start equ FirstParam+6
|
||||
|
||||
_TSEntry
|
||||
|
||||
lda TSPtr+2,s
|
||||
lda :TSPtr+2,s ; stuff the pointer in the direct page
|
||||
sta tmp1
|
||||
lda :TSPtr,s
|
||||
sta tmp0
|
||||
|
||||
lda :start,s ; put the range in the registers
|
||||
tax
|
||||
lda TSPtr,s
|
||||
lda :finish,s
|
||||
tay
|
||||
|
||||
jsr _LoadTileSet
|
||||
|
||||
_TSExit #0;#4
|
||||
_TSExit #0;#8
|
||||
|
||||
; CreateSpriteStamp(spriteId: Word, vbuffAddr: Word)
|
||||
; CreateSpriteStamp(spriteDescriptor: Word, vbuffAddr: Word)
|
||||
_TSCreateSpriteStamp
|
||||
:vbuff equ FirstParam
|
||||
:spriteId equ FirstParam+2
|
||||
|
@ -328,31 +361,41 @@ _TSCreateSpriteStamp
|
|||
|
||||
_TSExit #0;#4
|
||||
|
||||
; AddSprite(spriteSlot, spriteFlags, vbuff | cbuff, spriteX, spriteY)
|
||||
_TSAddSprite
|
||||
:spriteSlot equ FirstParam+0
|
||||
:spriteY equ FirstParam+2
|
||||
:spriteX equ FirstParam+4
|
||||
:spriteId equ FirstParam+6
|
||||
:spriteY equ FirstParam+0
|
||||
:spriteX equ FirstParam+2
|
||||
:vbuff equ FirstParam+4
|
||||
:spriteFlags equ FirstParam+6
|
||||
:spriteSlot equ FirstParam+8
|
||||
|
||||
_TSEntry
|
||||
|
||||
lda :spriteY,s
|
||||
and #$00FF
|
||||
xba
|
||||
sta :spriteY,s
|
||||
lda :spriteX,s
|
||||
and #$00FF
|
||||
ora :spriteY,s
|
||||
xba
|
||||
sta :spriteX,s
|
||||
lda :spriteY,s
|
||||
and #$00FF
|
||||
ora :spriteX,s
|
||||
tay
|
||||
|
||||
lda :spriteSlot,s
|
||||
tax
|
||||
|
||||
lda :spriteId,s
|
||||
lda :spriteFlags,s
|
||||
jsr _AddSprite
|
||||
|
||||
_TSExit #0;#8
|
||||
lda :spriteFlags,s
|
||||
tax
|
||||
lda :vbuff,s
|
||||
tay
|
||||
lda :spriteSlot,s
|
||||
jsr _UpdateSprite
|
||||
|
||||
_TSExit #0;#10
|
||||
|
||||
; MoveSprite(spriteSlot, x, y)
|
||||
_TSMoveSprite
|
||||
:spriteY equ FirstParam+0
|
||||
:spriteX equ FirstParam+2
|
||||
|
@ -368,6 +411,7 @@ _TSMoveSprite
|
|||
|
||||
_TSExit #0;#6
|
||||
|
||||
; UpdateSprite(spriteSlot, spriteFlags, vbuff)
|
||||
_TSUpdateSprite
|
||||
:vbuff equ FirstParam+0
|
||||
:spriteFlags equ FirstParam+2
|
||||
|
@ -457,6 +501,7 @@ _TSCopyPicToBG1
|
|||
:src_width equ tmp6
|
||||
:src_height equ tmp7
|
||||
:src_stride equ tmp8
|
||||
:src_flags equ tmp9
|
||||
|
||||
lda :width,s
|
||||
sta :src_width
|
||||
|
@ -467,9 +512,10 @@ _TSCopyPicToBG1
|
|||
|
||||
ldy BG1DataBank ; Pick the target data bank
|
||||
lda :flags,s
|
||||
bit #$0001
|
||||
beq *+4
|
||||
ldy BG1AltBank
|
||||
sta :src_flags
|
||||
; bit #$0001
|
||||
; beq *+4
|
||||
; ldy BG1AltBank
|
||||
|
||||
lda :ptr+2,s
|
||||
tax
|
||||
|
@ -662,6 +708,11 @@ _TSStartScript
|
|||
|
||||
_TSExit #0;#6
|
||||
; SetOverlay(top, bottom, proc)
|
||||
;
|
||||
; Overlays are handled as quasi-sprites. They need to be included in the y-sorted list of "stuff", but they are not drawn like
|
||||
; sprites. As such, they set a special flag in the SPRITE_ID field which allows them to be ignored for other purposes. Also,
|
||||
; they are not added into the "normal" sprite range on 0 - 15, but are stored in locations 16 and up to further seggregate them from
|
||||
; the rest of the system. A lot of the SPRITE_* locations are repurposed for Overlay-specific information.
|
||||
_TSSetOverlay
|
||||
:proc equ FirstParam+0
|
||||
:bottom equ FirstParam+4
|
||||
|
@ -669,16 +720,60 @@ _TSSetOverlay
|
|||
|
||||
_TSEntry
|
||||
|
||||
lda #1
|
||||
sta Overlays
|
||||
ldx #0 ; Always just use the first spot
|
||||
lda #SPRITE_OVERLAY
|
||||
; lda #SPRITE_OVERLAY+SPRITE_HIDE ; Type 2 overlays re-use the HIDE bit
|
||||
sta Overlays+OVERLAY_ID,x
|
||||
stz Overlays+OVERLAY_FLAGS,x
|
||||
|
||||
lda :top,s
|
||||
sta Overlays+2
|
||||
sta Overlays+OVERLAY_TOP,x
|
||||
lda :bottom,s
|
||||
sta Overlays+4
|
||||
; dec
|
||||
sta Overlays+OVERLAY_BOTTOM,x
|
||||
sec
|
||||
sbc :top,s
|
||||
; inc
|
||||
sta Overlays+OVERLAY_HEIGHT,x
|
||||
|
||||
lda :proc,s
|
||||
sta Overlays+6
|
||||
sta Overlays+OVERLAY_PROC,x
|
||||
lda :proc+2,s
|
||||
sta Overlays+8
|
||||
sta Overlays+OVERLAY_PROC+2,x
|
||||
|
||||
ldx #{MAX_SPRITES+0}*2 ; Adjust to call the generic routine
|
||||
jsr _InsertSprite
|
||||
|
||||
_TSExit #0;#8
|
||||
|
||||
; UpdateOverlay(top, bottom, proc)
|
||||
_TSUpdateOverlay
|
||||
:proc equ FirstParam+0
|
||||
:bottom equ FirstParam+4
|
||||
:top equ FirstParam+6
|
||||
|
||||
_TSEntry
|
||||
|
||||
ldx #0
|
||||
stz Overlays+OVERLAY_FLAGS,x
|
||||
|
||||
lda :top,s
|
||||
sta Overlays+OVERLAY_TOP
|
||||
lda :bottom,s
|
||||
; dec
|
||||
sta Overlays+OVERLAY_BOTTOM
|
||||
sec
|
||||
sbc :top,s
|
||||
; inc
|
||||
sta Overlays+OVERLAY_HEIGHT,x
|
||||
|
||||
lda :proc,s
|
||||
sta Overlays+OVERLAY_PROC
|
||||
lda :proc+2,s
|
||||
sta Overlays+OVERLAY_PROC+2
|
||||
|
||||
ldx #{MAX_SPRITES+0}*2 ; Adjust to call the generic routings
|
||||
jsr _UpdateSprite
|
||||
|
||||
_TSExit #0;#8
|
||||
|
||||
|
@ -792,6 +887,103 @@ _TSSetBG1Scale
|
|||
sta BG1Scaling
|
||||
_TSExit #0;#2
|
||||
|
||||
; Pointer GetAddress(addrId)
|
||||
_TSGetAddress
|
||||
:tblId equ FirstParam+0
|
||||
:output equ FirstParam+2
|
||||
|
||||
_TSEntry
|
||||
lda #0
|
||||
sta :output,s
|
||||
sta :output+2,s
|
||||
|
||||
lda :tblId,s
|
||||
cmp #scanlineHorzOffset
|
||||
bne :next_1
|
||||
|
||||
lda StartXMod164Tbl
|
||||
sta :output,s
|
||||
lda StartXMod164Tbl+2
|
||||
sta :output+2,s
|
||||
bra :out
|
||||
|
||||
:next_1 cmp #scanlineHorzOffset2
|
||||
bne :next_2
|
||||
|
||||
lda BG1StartXMod164Tbl
|
||||
sta :output,s
|
||||
lda BG1StartXMod164Tbl+2
|
||||
sta :output+2,s
|
||||
bra :out
|
||||
:next_2
|
||||
:out
|
||||
_TSExit #0;#2
|
||||
|
||||
; SetAddress(addrId, Pointer)
|
||||
_TSSetAddress
|
||||
:ptr equ FirstParam+0
|
||||
:tblId equ FirstParam+4
|
||||
|
||||
_TSEntry
|
||||
lda :tblId,s
|
||||
cmp #scanlineHorzOffset
|
||||
bne :next_1
|
||||
|
||||
lda :ptr,s
|
||||
sta StartXMod164Tbl
|
||||
lda :ptr+2,s
|
||||
sta StartXMod164Tbl+2
|
||||
bra :out
|
||||
|
||||
:next_1
|
||||
cmp #scanlineHorzOffset2
|
||||
bne :next_2
|
||||
|
||||
lda :ptr,s
|
||||
sta BG1StartXMod164Tbl
|
||||
lda :ptr+2,s
|
||||
sta BG1StartXMod164Tbl+2
|
||||
bra :out
|
||||
|
||||
:next_2 cmp #vblCallback
|
||||
bne :next_3
|
||||
|
||||
lda :ptr,s
|
||||
ora :ptr+2,s
|
||||
beq :vbl_restore
|
||||
|
||||
lda :ptr,s
|
||||
stal _VblTaskPatch+1 ; long addressing because we're patching code in the K bank
|
||||
lda :ptr+1,s
|
||||
stal _VblTaskPatch+2
|
||||
bra :out
|
||||
|
||||
:vbl_restore
|
||||
lda #_TaskStub
|
||||
stal _VblTaskPatch+1
|
||||
lda #>_TaskStub
|
||||
stal _VblTaskPatch+2
|
||||
bra :out
|
||||
:next_3
|
||||
:out
|
||||
_TSExit #0;#6
|
||||
|
||||
; CompileSpriteStamp(spriteId, vbuffAddr)
|
||||
_TSCompileSpriteStamp
|
||||
:vbuff equ FirstParam
|
||||
:spriteId equ FirstParam+2
|
||||
:output equ FirstParam+4
|
||||
|
||||
_TSEntry
|
||||
|
||||
lda :vbuff,s
|
||||
tax
|
||||
lda :spriteId,s
|
||||
jsr _CompileStampSet
|
||||
sta :output,s
|
||||
|
||||
_TSExit #0;#4
|
||||
|
||||
; Insert the GTE code
|
||||
|
||||
put Math.s
|
||||
|
@ -824,3 +1016,4 @@ _TSSetBG1Scale
|
|||
put blitter/Template.s
|
||||
put blitter/TemplateUtils.s
|
||||
put blitter/Blitter.s
|
||||
put blitter/PEISlammer.s
|
||||
|
|
|
@ -12,6 +12,7 @@ _InitBG1
|
|||
_CopyBinToBG1
|
||||
:src_width equ tmp6
|
||||
:src_height equ tmp7
|
||||
:src_flags equ tmp9
|
||||
|
||||
clc
|
||||
adc #8 ; Advance over the header
|
||||
|
@ -21,10 +22,47 @@ _CopyBinToBG1
|
|||
sta :src_width
|
||||
lda #208
|
||||
sta :src_height
|
||||
lda #COPY_PIC_NORMAL
|
||||
sta :src_flags
|
||||
|
||||
pla
|
||||
jmp _CopyToBG1
|
||||
|
||||
; Reset the BG1 Y-table depending on the rendering mode
|
||||
;
|
||||
; A = mode
|
||||
; 0 = default (base = $1800, stride = 256)
|
||||
; 1 = scanline (base = $0, stride = 327)
|
||||
_ResetBG1YTable
|
||||
:base equ tmp0
|
||||
:stride equ tmp1
|
||||
cmp #1 ; scanline mode?
|
||||
bne :default
|
||||
lda #0
|
||||
sta :base
|
||||
lda #327
|
||||
sta :stride
|
||||
bra :begin
|
||||
:default
|
||||
lda #$1800
|
||||
sta :base
|
||||
lda #256
|
||||
sta :stride
|
||||
:begin
|
||||
ldx #0
|
||||
lda :base
|
||||
:loop
|
||||
sta BG1YTable,x
|
||||
sta BG1YTable+{208*2},x
|
||||
|
||||
clc
|
||||
adc :stride
|
||||
|
||||
inx
|
||||
inx
|
||||
cpx #{208*2}
|
||||
bcc :loop
|
||||
rts
|
||||
|
||||
; Copy a IIgs $C1 picture into BG1. Assumes the file is the correct size (320 x 200)
|
||||
;
|
||||
|
@ -35,6 +73,7 @@ _CopyPicToBG1
|
|||
:src_width equ tmp6
|
||||
:src_height equ tmp7
|
||||
:src_stride equ tmp8
|
||||
:src_flags equ tmp9
|
||||
|
||||
pha
|
||||
lda #160
|
||||
|
@ -42,6 +81,8 @@ _CopyPicToBG1
|
|||
sta :src_stride
|
||||
lda #200
|
||||
sta :src_height
|
||||
lda #COPY_PIC_NORMAL
|
||||
sta :src_flags
|
||||
pla
|
||||
jmp _CopyToBG1
|
||||
|
||||
|
@ -54,24 +95,64 @@ _CopyToBG1
|
|||
:src_width equ tmp6
|
||||
:src_height equ tmp7
|
||||
:src_stride equ tmp8
|
||||
:src_flags equ tmp9
|
||||
:dstptr2 equ tmp10
|
||||
|
||||
; scanline mode is tricky -- there's not enough space to make two full copies of a 328x200 bitmap buffer, but we can
|
||||
; *barely* fit a (164 + 163) x 200 buffer. And, since the zero offset could use either end, this covers all of the cases.
|
||||
|
||||
sta :srcptr
|
||||
stx :srcptr+2
|
||||
sty :dstptr+2 ; Everything goes into this bank
|
||||
sty :dstptr2+2
|
||||
|
||||
; "Normal" BG1 mode as a stride of 164 bytes and mirrors the BG0 size (328 x 208)
|
||||
; In "Scanline" mode, the BG1 is treated as a 328x200 bitfield with each horizontal line doubled
|
||||
|
||||
lda :src_flags
|
||||
cmp #COPY_PIC_NORMAL
|
||||
bne *+5
|
||||
jmp :_CopyToBG1Normal
|
||||
|
||||
cmp #COPY_PIC_SCANLINE
|
||||
bne *+5
|
||||
jmp :_CopyToBG1SCanline
|
||||
|
||||
rts ; Flag do not match a known copy mode
|
||||
|
||||
:_CopyToBG1SCanline
|
||||
lda #0 ; Start a byte 1 because odd offsets might go back 1 byte and don't want to wrap around
|
||||
sta :dstptr
|
||||
clc
|
||||
adc #164 ; The first part is 1-byte short, the second part is a full 164 bytes
|
||||
sta :dstptr2
|
||||
|
||||
lda :src_width
|
||||
min #164
|
||||
sta :src_width
|
||||
|
||||
lda :src_height
|
||||
min #200
|
||||
sta :src_height
|
||||
|
||||
stz :line_cnt
|
||||
:rloop
|
||||
lda :line_cnt ; get the pointer to the code field line
|
||||
asl
|
||||
tax
|
||||
|
||||
lda BG1YTable,x
|
||||
sta :dstptr
|
||||
|
||||
ldy #0 ; move forward in the image data and image data
|
||||
; Handle first word as a special case
|
||||
|
||||
lda [:srcptr],y
|
||||
sta [:dstptr2],y ; copy directly into the 164-byte buffer
|
||||
iny
|
||||
xba
|
||||
sep #$20
|
||||
sta [:dstptr],y ; only copy the high byte because the previous line occupies the low byte
|
||||
rep #$20
|
||||
iny
|
||||
|
||||
:cloop
|
||||
lda [:srcptr],y
|
||||
sta [:dstptr],y
|
||||
sta [:dstptr2],y
|
||||
|
||||
iny
|
||||
iny
|
||||
|
@ -79,14 +160,12 @@ _CopyToBG1
|
|||
cpy :src_width
|
||||
bcc :cloop
|
||||
|
||||
ldy #164
|
||||
lda [:srcptr] ; Duplicate the last couple of words in the extra space at the end of the line
|
||||
sta [:dstptr],y
|
||||
|
||||
ldy #2
|
||||
lda [:srcptr],y
|
||||
ldy #166
|
||||
sta [:dstptr],y
|
||||
lda :dstptr
|
||||
clc
|
||||
adc #327
|
||||
sta :dstptr
|
||||
adc #164
|
||||
sta :dstptr2
|
||||
|
||||
lda :srcptr
|
||||
clc
|
||||
|
@ -99,6 +178,49 @@ _CopyToBG1
|
|||
bcc :rloop
|
||||
rts
|
||||
|
||||
:_CopyToBG1Normal
|
||||
stz :line_cnt
|
||||
:rloop2
|
||||
lda :line_cnt ; get the pointer to the code field line
|
||||
asl
|
||||
tax
|
||||
|
||||
lda BG1YTable,x
|
||||
sta :dstptr
|
||||
clc
|
||||
adc #164
|
||||
sta :dstptr2
|
||||
|
||||
ldy #0 ; move forward in the image data and image data
|
||||
:cloop2
|
||||
lda [:srcptr],y
|
||||
sta [:dstptr],y
|
||||
|
||||
iny
|
||||
iny
|
||||
|
||||
cpy :src_width
|
||||
bcc :cloop2
|
||||
|
||||
ldy #0
|
||||
lda [:dstptr],y ; Duplicate the last couple of words in the extra space at the end of the line
|
||||
sta [:dstptr2],y
|
||||
|
||||
ldy #2
|
||||
lda [:dstptr],y
|
||||
sta [:dstptr2],y
|
||||
|
||||
lda :srcptr
|
||||
clc
|
||||
adc :src_stride
|
||||
sta :srcptr
|
||||
|
||||
inc :line_cnt
|
||||
lda :line_cnt
|
||||
cmp :src_height
|
||||
bcc :rloop2
|
||||
rts
|
||||
|
||||
_SetBG1XPos
|
||||
cmp BG1StartX
|
||||
beq :out ; Easy, if nothing changed, then nothing changes
|
||||
|
@ -140,6 +262,35 @@ _ApplyBG1XPosPre
|
|||
sta BG1StartXMod164
|
||||
rts
|
||||
|
||||
; Save as _ApplyBG1XPos, but we pretend that StartXMod164 is always zero and deal with the per-line offset adjustment in
|
||||
; _ApplyScanlineBG1YPos. The tweak here is that the buffer is only 160 bytes wide in scanine mode, instead of 164 bytes wide
|
||||
_ApplyScanlineBG1XPos
|
||||
lda BG1StartXMod164 ; How far into the BG1 buffer is the left edge?
|
||||
tay
|
||||
|
||||
phd ; save the direct page because we are going to switch to the
|
||||
lda BlitterDP ; blitter direct page space and fill in the addresses
|
||||
tcd
|
||||
|
||||
ldx #0
|
||||
; tya
|
||||
lda #0
|
||||
:loop
|
||||
sta 00,x ; store the value
|
||||
inc
|
||||
inc
|
||||
cmp #164
|
||||
bcc *+5
|
||||
sbc #164
|
||||
|
||||
inx
|
||||
inx
|
||||
cpx #164
|
||||
bcc :loop
|
||||
|
||||
pld
|
||||
rts
|
||||
|
||||
_ApplyBG1XPos
|
||||
lda #162
|
||||
sec
|
||||
|
@ -196,6 +347,163 @@ _ClearBG1Buffer
|
|||
plb
|
||||
rts
|
||||
|
||||
; Variation to take care of horizontal adjustments within the BG1 buffer to compensate for the
|
||||
; per-scanline BG0 displacement. It is up to the caller to manage the memeory layout to make
|
||||
; this visually work.
|
||||
;
|
||||
; In the scanline mode we have to be able to adjust the base address of each BG1 line up to
|
||||
; a full screen, so scanline mode treats bank as a 640x200 pixel bitmap (64000 byte).
|
||||
;
|
||||
; This is just a limitation of scanline displacement mode that there is no extra vertical space.
|
||||
_ApplyScanlineBG1YPos
|
||||
:stk_save equ tmp0
|
||||
:virt_line_x2 equ tmp1
|
||||
:lines_left_x2 equ tmp2
|
||||
:draw_count_x2 equ tmp3
|
||||
:ytbl_idx_x2 equ tmp4
|
||||
:shift_value equ tmp5
|
||||
|
||||
; Avoid local var collision
|
||||
:ptr2 equ tmp8
|
||||
:ytbl_idx_pos_x2 equ tmp10
|
||||
:virt_line_pos_x2 equ tmp11
|
||||
:total_left_x2 equ tmp12
|
||||
:current_count_x2 equ tmp13
|
||||
:ptr equ tmp14
|
||||
|
||||
lda StartXMod164Tbl
|
||||
sta :ptr
|
||||
lda StartXMod164Tbl+2
|
||||
sta :ptr+2
|
||||
|
||||
lda BG1StartXMod164Tbl
|
||||
sta :ptr2
|
||||
lda BG1StartXMod164Tbl+2
|
||||
sta :ptr2+2
|
||||
ora :ptr2
|
||||
|
||||
lda BG1StartY
|
||||
jsr Mod208
|
||||
sta BG1StartYMod208
|
||||
asl
|
||||
sta :ytbl_idx_pos_x2 ; Start copying from the first entry in the table
|
||||
|
||||
lda StartYMod208 ; This is the base line of the virtual screen
|
||||
asl
|
||||
sta :virt_line_pos_x2
|
||||
tay
|
||||
|
||||
lda ScreenHeight
|
||||
asl
|
||||
sta :total_left_x2
|
||||
|
||||
:loop0
|
||||
lda [:ptr],y
|
||||
tax
|
||||
|
||||
and #$FF00 ; Determine how many sequential lines have this mod value
|
||||
xba
|
||||
inc
|
||||
asl
|
||||
min :total_left_x2 ; Don't draw more than the number of lines that are left to process
|
||||
sta :current_count_x2 ; Save a copy for later
|
||||
|
||||
sta :lines_left_x2 ; Set the parameter
|
||||
lda :ytbl_idx_pos_x2 ; Set the parameter
|
||||
sta :ytbl_idx_x2
|
||||
sty :virt_line_x2 ; Set the parameter
|
||||
txa ; Put the X mod 164 value in the offset value
|
||||
and #$00FF
|
||||
sta :shift_value
|
||||
|
||||
jsr :_ApplyConstBG1YPos ; Shift this range by a constant amount
|
||||
|
||||
clc
|
||||
lda :virt_line_pos_x2
|
||||
adc :current_count_x2
|
||||
cmp #208*2 ; Do the modulo check in this loop
|
||||
bcc *+5
|
||||
sbc #208*2
|
||||
sta :virt_line_pos_x2
|
||||
tay
|
||||
|
||||
clc
|
||||
lda :ytbl_idx_pos_x2
|
||||
adc :current_count_x2
|
||||
sta :ytbl_idx_pos_x2
|
||||
|
||||
lda :total_left_x2
|
||||
sec
|
||||
sbc :current_count_x2
|
||||
sta :total_left_x2
|
||||
bne :loop0
|
||||
|
||||
rts
|
||||
|
||||
:_ApplyConstBG1YPos
|
||||
|
||||
lda #164
|
||||
sec
|
||||
sbc :shift_value
|
||||
clc
|
||||
adc BG1StartXMod164
|
||||
cmp #164+1
|
||||
bcc *+5
|
||||
sbc #164
|
||||
sta :shift_value ; Base shift value
|
||||
|
||||
cmp #165
|
||||
bcc *+4
|
||||
brk $04
|
||||
|
||||
phb ; Save the existing bank
|
||||
tsc
|
||||
sta :stk_save
|
||||
|
||||
:loop
|
||||
ldx :virt_line_x2
|
||||
|
||||
ldal BTableHigh,x ; Get the bank
|
||||
pha
|
||||
plb
|
||||
|
||||
ldal BTableLow,x ; Get the address of the first code field line
|
||||
tay
|
||||
|
||||
txa ; Calculate number of lines to draw on this iteration
|
||||
and #$001E
|
||||
eor #$FFFF
|
||||
sec
|
||||
adc #32
|
||||
min :lines_left_x2
|
||||
sta :draw_count_x2
|
||||
tax
|
||||
|
||||
lda :ytbl_idx_x2 ; Read from this location in the BG1YTable
|
||||
; clc
|
||||
; CopyBG1YTableToBG1Addr3 :shift_value
|
||||
CopyBG1YTableToBG1Addr4 :shift_value;blttmp
|
||||
|
||||
lda :virt_line_x2 ; advance to the virtual line after
|
||||
adc :draw_count_x2 ; filled in
|
||||
sta :virt_line_x2
|
||||
|
||||
lda :ytbl_idx_x2
|
||||
adc :draw_count_x2
|
||||
sta :ytbl_idx_x2
|
||||
|
||||
lda :lines_left_x2 ; subtract the number of lines we just completed
|
||||
sec
|
||||
sbc :draw_count_x2
|
||||
sta :lines_left_x2
|
||||
|
||||
jne :loop
|
||||
|
||||
lda :stk_save
|
||||
tcs
|
||||
plb
|
||||
rts
|
||||
|
||||
; Everytime either BG1 or BG0 Y-position changes, we have to update the Y-register
|
||||
; value in all of the code fields (within the visible screen)
|
||||
_ApplyBG1YPos
|
||||
|
@ -353,8 +661,138 @@ CopyBG1YTableToBG1Addr
|
|||
sta: BG1_ADDR+$0000,y
|
||||
:none rts
|
||||
|
||||
; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position
|
||||
; with a constant shift applied
|
||||
;
|
||||
; A = index into the BG1YTable array (x2)
|
||||
; Y = starting line * $1000
|
||||
; X = number of lines (x2)
|
||||
; ]1 = offset
|
||||
CopyBG1YTableToBG1Addr3 mac
|
||||
jmp (tbl,x)
|
||||
tbl da none
|
||||
da do01,do02,do03,do04
|
||||
da do05,do06,do07,do08
|
||||
da do09,do10,do11,do12
|
||||
da do13,do14,do15,do16
|
||||
do15 tax
|
||||
jmp x15
|
||||
do14 tax
|
||||
jmp x14
|
||||
do13 tax
|
||||
jmp x13
|
||||
do12 tax
|
||||
jmp x12
|
||||
do11 tax
|
||||
jmp x11
|
||||
do10 tax
|
||||
jmp x10
|
||||
do09 tax
|
||||
jmp x09
|
||||
do08 tax
|
||||
jmp x08
|
||||
do07 tax
|
||||
jmp x07
|
||||
do06 tax
|
||||
jmp x06
|
||||
do05 tax
|
||||
jmp x05
|
||||
do04 tax
|
||||
jmp x04
|
||||
do03 tax
|
||||
jmp x03
|
||||
do02 tax
|
||||
jmp x02
|
||||
do01 tax
|
||||
jmp x01
|
||||
do16 tax
|
||||
ldal BG1YTable+30,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$F000,y
|
||||
x15 ldal BG1YTable+28,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$E000,y
|
||||
x14 ldal BG1YTable+26,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$D000,y
|
||||
x13 ldal BG1YTable+24,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$C000,y
|
||||
x12 ldal BG1YTable+22,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$B000,y
|
||||
x11 ldal BG1YTable+20,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$A000,y
|
||||
x10 ldal BG1YTable+18,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$9000,y
|
||||
x09 ldal BG1YTable+16,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$8000,y
|
||||
x08 ldal BG1YTable+14,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$7000,y
|
||||
x07 ldal BG1YTable+12,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$6000,y
|
||||
x06 ldal BG1YTable+10,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$5000,y
|
||||
x05 ldal BG1YTable+08,x
|
||||
adc ]1
|
||||
sta: BG1_ADDR+$4000,y
|
||||
x04 ldal BG1YTable+06,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$3000,y
|
||||
x03 ldal BG1YTable+04,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$2000,y
|
||||
x02 ldal BG1YTable+02,x
|
||||
adc ]1
|
||||
sta BG1_ADDR+$1000,y
|
||||
x01 ldal BG1YTable+00,x
|
||||
adc ]1
|
||||
sta: BG1_ADDR+$0000,y
|
||||
none <<<
|
||||
|
||||
; Copy routine to move BG1YTable entries into BG1_ADDR position with an additional
|
||||
; shift on every line form the user-provided BG1StartXMod164Tbl.
|
||||
;
|
||||
; A = index into the BG1YTable array (x2)
|
||||
; Y = starting line * $1000
|
||||
; X = number of lines (x2)
|
||||
;
|
||||
; ]1 = constant shift value
|
||||
; ]2 = temp storage space
|
||||
CopyBG1YTableToBG1Addr4 mac
|
||||
phy ; save the registers
|
||||
phx
|
||||
phb
|
||||
pha
|
||||
jsr _SetDataBank ; Set to toolbox data bank
|
||||
|
||||
clc
|
||||
lda 1,s ; virtual_index_x2
|
||||
adc BG1StartXMod164Tbl ; Get the starting address in the array for this chunk
|
||||
tay
|
||||
|
||||
lda BG1StartXMod164Tbl+1 ; Set the bank to the array location
|
||||
pha
|
||||
plb
|
||||
plb
|
||||
|
||||
pla ; POp back the original value
|
||||
ApplyBG1ModXToShift ]1;]2 ; Copy the array into direct page storage and apply the shift
|
||||
|
||||
plb ; Restore the code field bank
|
||||
plx ; x is used directly in this routine
|
||||
ply
|
||||
ApplyBG1ShiftToCode ]2
|
||||
<<<
|
||||
|
||||
; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position with an additional
|
||||
; shift. This has to be split into two
|
||||
; shift on every line. This has to be split into two
|
||||
;
|
||||
; A = index into the BG1YTable array (x2)
|
||||
; Y = starting line * $1000
|
||||
|
@ -504,3 +942,105 @@ ApplyBG1OffsetValues
|
|||
:do01 ldal BG1YCache+00
|
||||
sta: BG1_ADDR+$0000,y
|
||||
:none rts
|
||||
|
||||
; Apply the per-scanline shift from the BG1StartXMod164Tbl pointer. Save the relevant values to the
|
||||
; direct page since the array could be in any bank.
|
||||
;
|
||||
; This does bounds checking to make sure the shift value remains in the valid range
|
||||
;
|
||||
; ]1 = source array offset
|
||||
; ]2 = constant shift value
|
||||
; ]3 = destination address
|
||||
_BG1ShiftTemplate mac
|
||||
lda ]1,y ; Load the value from the array
|
||||
adc ]2 ; Add to the direct page shift_value
|
||||
cmp #165 ; If below this value, we're good
|
||||
bcc *+6
|
||||
sbc #164
|
||||
clc
|
||||
adcl BG1YTable+]1,x
|
||||
sta ]3+]1
|
||||
<<<
|
||||
|
||||
AToX mac
|
||||
tax
|
||||
brl ]1
|
||||
<<<
|
||||
|
||||
ApplyBG1ModXToShift mac
|
||||
jmp (agmxts_tbl,x)
|
||||
agmxts_tbl da none
|
||||
da do01,do02,do03,do04
|
||||
da do05,do06,do07,do08
|
||||
da do09,do10,do11,do12
|
||||
da do13,do14,do15,do16
|
||||
do16 AToX o16
|
||||
do15 AToX o15
|
||||
do14 AToX o14
|
||||
do13 AToX o13
|
||||
do12 AToX o12
|
||||
do11 AToX o11
|
||||
do10 AToX o10
|
||||
do09 AToX o09
|
||||
do08 AToX o08
|
||||
do07 AToX o07
|
||||
do06 AToX o06
|
||||
do05 AToX o05
|
||||
do04 AToX o04
|
||||
do03 AToX o03
|
||||
do02 AToX o02
|
||||
do01 AToX o01
|
||||
|
||||
o16 _BG1ShiftTemplate 30;]1;]2
|
||||
o15 _BG1ShiftTemplate 28;]1;]2
|
||||
o14 _BG1ShiftTemplate 26;]1;]2
|
||||
o13 _BG1ShiftTemplate 24;]1;]2
|
||||
o12 _BG1ShiftTemplate 22;]1;]2
|
||||
o11 _BG1ShiftTemplate 20;]1;]2
|
||||
o10 _BG1ShiftTemplate 18;]1;]2
|
||||
o09 _BG1ShiftTemplate 16;]1;]2
|
||||
o08 _BG1ShiftTemplate 14;]1;]2
|
||||
o07 _BG1ShiftTemplate 12;]1;]2
|
||||
o06 _BG1ShiftTemplate 10;]1;]2
|
||||
o05 _BG1ShiftTemplate 8;]1;]2
|
||||
o04 _BG1ShiftTemplate 6;]1;]2
|
||||
o03 _BG1ShiftTemplate 4;]1;]2
|
||||
o02 _BG1ShiftTemplate 2;]1;]2
|
||||
o01 _BG1ShiftTemplate 0;]1;]2
|
||||
none <<<
|
||||
|
||||
; After the values are saved, the data bank can be repointed at the current code bank and the values copied in
|
||||
; from the direct page
|
||||
;
|
||||
; ]1 = offset in temp buffer
|
||||
; ]2 = address of temp buffer
|
||||
; ]3 = 4k offset in code buffer
|
||||
_BG1ShiftToCodeTemplate mac
|
||||
lda ]2+]1
|
||||
sta: BG1_ADDR+]3,y
|
||||
<<<
|
||||
|
||||
ApplyBG1ShiftToCode mac
|
||||
jmp (abstc_tbl,x)
|
||||
abstc_tbl da none
|
||||
da do01,do02,do03,do04
|
||||
da do05,do06,do07,do08
|
||||
da do09,do10,do11,do12
|
||||
da do13,do14,do15,do16
|
||||
do16 _BG1ShiftToCodeTemplate 30;]1;$F000
|
||||
do15 _BG1ShiftToCodeTemplate 28;]1;$E000
|
||||
do14 _BG1ShiftToCodeTemplate 26;]1;$D000
|
||||
do13 _BG1ShiftToCodeTemplate 24;]1;$C000
|
||||
do12 _BG1ShiftToCodeTemplate 22;]1;$B000
|
||||
do11 _BG1ShiftToCodeTemplate 20;]1;$A000
|
||||
do10 _BG1ShiftToCodeTemplate 18;]1;$9000
|
||||
do09 _BG1ShiftToCodeTemplate 16;]1;$8000
|
||||
do08 _BG1ShiftToCodeTemplate 14;]1;$7000
|
||||
do07 _BG1ShiftToCodeTemplate 12;]1;$6000
|
||||
do06 _BG1ShiftToCodeTemplate 10;]1;$5000
|
||||
do05 _BG1ShiftToCodeTemplate 8;]1;$4000
|
||||
do04 _BG1ShiftToCodeTemplate 6;]1;$3000
|
||||
do03 _BG1ShiftToCodeTemplate 4;]1;$2000
|
||||
do02 _BG1ShiftToCodeTemplate 2;]1;$1000
|
||||
do01 _BG1ShiftToCodeTemplate 0;]1;$0000
|
||||
none <<<
|
|
@ -13,6 +13,11 @@ _BltRange
|
|||
:exit_ptr equ tmp0
|
||||
:jmp_low_save equ tmp2
|
||||
|
||||
sty :jmp_low_save ; Steal some temp space and check for empty ranges
|
||||
cpx :jmp_low_save ; This makes it simpler for some callers
|
||||
bcc *+3
|
||||
rts
|
||||
|
||||
phb ; preserve the bank register
|
||||
clc`
|
||||
|
||||
|
@ -57,16 +62,19 @@ _BltRange
|
|||
lda EngineMode
|
||||
bit #ENGINE_MODE_TWO_LAYER
|
||||
beq :skip_bank
|
||||
|
||||
lda RenderFlags
|
||||
bit #RENDER_ALT_BG1
|
||||
beq :primary
|
||||
|
||||
lda BG1AltBank
|
||||
bra :alt
|
||||
|
||||
:primary lda BG1DataBank
|
||||
:alt
|
||||
; TODO: Switch to loading the selected BG1 bank. No special "Alt" bank
|
||||
;
|
||||
; lda RenderFlags
|
||||
; bit #RENDER_ALT_BG1
|
||||
; beq :primary
|
||||
;
|
||||
; lda BG1AltBank
|
||||
; bra :alt
|
||||
;
|
||||
;:primary lda BG1DataBank
|
||||
;:alt
|
||||
lda BG1DataBank
|
||||
pha
|
||||
plb
|
||||
|
||||
|
@ -81,7 +89,7 @@ _BltRange
|
|||
_R0W1
|
||||
tsc ; save the stack pointer
|
||||
stal stk_save+1
|
||||
|
||||
|
||||
blt_entry jml $000000 ; Jump into the blitter code $XX/YY00
|
||||
|
||||
blt_return _R0W0
|
||||
|
|
1011
src/blitter/Horz.s
1011
src/blitter/Horz.s
File diff suppressed because it is too large
Load Diff
|
@ -6,19 +6,33 @@
|
|||
; slammer, note that page-aligned addresses repeat every 8 scan lines and some lines would need
|
||||
; to be split into two slams to keep the direct page aligned.
|
||||
;
|
||||
; At best, this saves 1 cycles per word, or 80 cycles for a full screen -- which is only about
|
||||
; At best, this saves 1 cycles per word, or 80 cycles for a full scanline -- which is only about
|
||||
; 12 additional instructions, so this is an optimization that is unlikely to lead to a net
|
||||
; improvement.
|
||||
;
|
||||
; X = first line (inclusive), valid range of 0 to 199
|
||||
; Y = last line (exclusive), valid range >X up to 200
|
||||
_PEISlam
|
||||
cpx #200
|
||||
bcc *+3
|
||||
rts
|
||||
cpy #201
|
||||
bcc *+3
|
||||
rts
|
||||
|
||||
txa
|
||||
stal :screen_width_1
|
||||
tya
|
||||
cmpl :screen_width_1
|
||||
bcs *+3
|
||||
rts
|
||||
|
||||
|
||||
lda ScreenWidth
|
||||
dec
|
||||
stal :screen_width_1 ; save the width-1 outside of the direct page
|
||||
|
||||
lda #:pei_end ; patch the PEI entry address
|
||||
and #$FFFE ; should always be even, but....
|
||||
sec
|
||||
sbc ScreenWidth
|
||||
stal :inner+1
|
||||
|
|
|
@ -6,8 +6,13 @@
|
|||
;
|
||||
; This is about as fast of a rotation as we can do.
|
||||
;
|
||||
; When possible, off-screen locations are calculate to produce an address of $FFFE, so that the last two bytes
|
||||
; When possible, off-screen locations are calculated to produce an address of $FFFE, so that the last two bytes
|
||||
; of the BG1 data buffer provides the "fill value".
|
||||
;
|
||||
; Having a fixed table of addresses is limiting due to the size an inability to control what happens at the
|
||||
; boundaries. Consider generating some pre-processed step + error parameters that can be used in a fast
|
||||
; DDA stepper to allow a more compact representation or different (scale, angle) pairs. This could allow for
|
||||
; a full range of 256 rotation angles + multiple scalings.
|
||||
|
||||
ANGLEBNK EXT
|
||||
_ApplyBG1XPosAngle
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
DP_ADDR equ entry_1-base+1 ; offset to patch in the direct page for dynamic tiles
|
||||
BG1_ADDR equ entry_2-base+1 ; offset to patch in the Y-reg for BG1 (dp),y addressing
|
||||
STK_ADDR equ entry_3-base+1 ; offset to patch in the stack (SHR) right edge address
|
||||
; BNK_ADDR equ entry_0-base+1 ; offset to patch in the address of a Bank 0 memory location to load the bank register
|
||||
|
||||
DP_ENTRY equ entry_1-base
|
||||
TWO_LYR_ENTRY equ entry_2-base
|
||||
ONE_LYR_ENTRY equ entry_3-base
|
||||
; BANK_ENTRY equ entry_0-base
|
||||
|
||||
CODE_ENTRY_OPCODE equ entry_jmp-base
|
||||
CODE_ENTRY equ entry_jmp-base+1 ; low byte of the page-aligned jump address
|
||||
|
@ -16,19 +18,26 @@ ODD_ENTRY equ odd_entry-base+1
|
|||
CODE_TOP equ loop-base
|
||||
CODE_LEN equ top-base
|
||||
CODE_EXIT equ even_exit-base
|
||||
OPCODE_SAVE equ odd_save-base ; spot to save the code field opcode when patching exit BRA
|
||||
OPCODE_HIGH_SAVE equ odd_save-base+2 ; save the third byte
|
||||
OPCODE_SAVE equ odd_low_save-base ; spot to save the code field opcode when patching exit BRA
|
||||
OPCODE_HIGH_SAVE equ odd_high_save-base ; save the second and third byte
|
||||
FULL_RETURN equ full_return-base ; offset that returns from the blitter
|
||||
ENABLE_INT equ enable_int-base ; offset that re-enable interrupts and continues
|
||||
LINES_PER_BANK equ 16
|
||||
SNIPPET_BASE equ snippets-base
|
||||
|
||||
; offsets from each snippet base address for the different entry points
|
||||
|
||||
SNIPPET_ENTRY_1 equ 0 ; two layer + dynamic tile + sprite
|
||||
SNIPPET_ENTRY_2 equ 4 ; (two layer | dynamic tile) + sprite
|
||||
SNIPPET_ENTRY_3 equ 18 ; sprite under dynamic tile
|
||||
SNIPPET_ENTRY_4 equ 19 ; two layer + dynamic tile (no sprite)
|
||||
|
||||
; Locations that need the page offset added
|
||||
PagePatches da {long_0-base+2}
|
||||
da {long_1-base+2}
|
||||
da {long_2-base+2}
|
||||
da {long_3-base+2}
|
||||
da {long_4-base+2}
|
||||
; da {long_4-base+2}
|
||||
da {long_5-base+2}
|
||||
da {long_6-base+2}
|
||||
da {odd_entry-base+2}
|
||||
|
@ -41,9 +50,9 @@ PagePatches da {long_0-base+2}
|
|||
; da {jmp_rtn_2-base+2}
|
||||
|
||||
]index equ 0
|
||||
lup 82 ; All the snippet addresses. The two JMP
|
||||
da {snippets-base+{]index*32}+31} ; instructions are at the end of each of
|
||||
da {snippets-base+{]index*32}+28} ; the 32-byte buffers
|
||||
lup 82 ; Patch anything that needs updating within the snippets
|
||||
da {snippets-base+{]index*32}+17}
|
||||
da {snippets-base+{]index*32}+29}
|
||||
]index equ ]index+1
|
||||
--^
|
||||
PagePatchNum equ *-PagePatches
|
||||
|
@ -53,7 +62,7 @@ BankPatches da {long_0-base+3}
|
|||
da {long_1-base+3}
|
||||
da {long_2-base+3}
|
||||
da {long_3-base+3}
|
||||
da {long_4-base+3}
|
||||
; da {long_4-base+3}
|
||||
da {long_5-base+3}
|
||||
da {long_6-base+3}
|
||||
BankPatchNum equ *-BankPatches
|
||||
|
@ -66,6 +75,9 @@ BankPatchNum equ *-BankPatches
|
|||
; the code is assembled on a page boundary to help with alignment
|
||||
ds \,$00 ; pad to the next page boundary
|
||||
base
|
||||
;entry_0 lda #0000 ; Used to set per-scanline bank register
|
||||
; tcs
|
||||
; plb
|
||||
entry_1 ldx #0000 ; Used for LDA 00,x addressing (Dynamic Tiles)
|
||||
entry_2 ldy #0000 ; Used for LDA (00),y addressing (Second Layer; BG1)
|
||||
entry_3 lda #0000 ; Sets screen address (right edge)
|
||||
|
@ -82,7 +94,7 @@ entry_jmp jmp $0100
|
|||
; update the low-byte of the address, the means it takes only
|
||||
; an amortized 4-cycles per line to set the entry point break
|
||||
|
||||
right_odd bit #$000B ; Check the bottom nibble to quickly identify a PEA instruction
|
||||
bit #$000B ; Check the bottom nibble to quickly identify a PEA instruction
|
||||
bne r_is_not_pea ; This costs 5 cycles in the fast-path
|
||||
|
||||
xba ; fast code for PEA
|
||||
|
@ -138,17 +150,17 @@ jmp_rtn_1 jmp l_jmp_rtn-base ; Could inline the code and
|
|||
; 8 or 16 lines in order to give the system time to handle interrupts.
|
||||
enable_int ldal stk_save+1 ; restore the stack
|
||||
tcs
|
||||
sep #$20 ; 8-bit mode
|
||||
ldal STATE_REG ; Read Bank 0 / Write Bank 0
|
||||
and #$CF
|
||||
sep #$30 ; 8-bit mode
|
||||
ldal STATE_REG
|
||||
tax ; Save the value
|
||||
and #$CF ; Read Bank 0 / Write Bank 0
|
||||
stal STATE_REG
|
||||
cli
|
||||
nop ; Give a couple of cycles
|
||||
sei
|
||||
ldal STATE_REG
|
||||
ora #$10 ; Read Bank 0 / Write Bank 1
|
||||
txa ; Restore the state
|
||||
stal STATE_REG
|
||||
rep #$20
|
||||
rep #$30
|
||||
bra entry_1
|
||||
|
||||
; This is the spot that needs to be page-aligned. In addition to simplifying the entry address
|
||||
|
@ -166,38 +178,39 @@ loop lup 82 ; +6 Set up 82 PEA instruc
|
|||
loop_back jmp loop-base ; +252 Ensure execution continues to loop around
|
||||
loop_exit_3 jmp even_exit-base ; +255
|
||||
|
||||
long_5
|
||||
odd_exit ldal l_is_jmp+1-base
|
||||
bit #$000B
|
||||
odd_exit sep #$21 ; 8-bit mode and set the carry just in case we get to a snippet JMP
|
||||
long_5 ldal OPCODE_SAVE ; Load the opcode that was saved
|
||||
bit #$0B
|
||||
bne :chk_jmp
|
||||
|
||||
sep #$20
|
||||
long_6 ldal l_is_jmp+3-base ; get the high byte of the PEA operand
|
||||
long_6 ldal OPCODE_HIGH_SAVE+1 ; get the high byte of the PEA operand
|
||||
|
||||
; Fall-through when we have to push a byte on the left edge. Must be 8-bit on entry. Optimized
|
||||
; for the PEA $0000 case -- only 19 cycles to handle the edge, so pretty good
|
||||
:left_byte
|
||||
; for the PEA $0000 case -- only 17 cycles to handle the edge, so pretty good
|
||||
|
||||
pha
|
||||
rep #$20
|
||||
rep #$21
|
||||
|
||||
; JMP opcode = $4C, JML opcode = $5C
|
||||
even_exit jmp $1000 ; Jump to the next line.
|
||||
ds 1 ; space so that the last line in a bank can be patched into a JML
|
||||
|
||||
:chk_jmp
|
||||
bit #$0040
|
||||
:chk_jmp mx %10 ; 8-bit accumulator / 16-bit registers
|
||||
bit #$40
|
||||
bne l_is_jmp
|
||||
|
||||
long_4 stal *+4-base
|
||||
dfb $00,$00
|
||||
rep #$20 ; saved 3 cycles using 8-bit mode, but give it back here.
|
||||
odd_low_save dfb $00,$00 ; save the first and second bytes of the code field. Works for LDA dp,x and LDA (0),y
|
||||
l_jmp_rtn xba
|
||||
sep #$20
|
||||
pha
|
||||
rep #$61 ; Clear everything C, V and M
|
||||
bra even_exit
|
||||
|
||||
l_is_jmp sec ; Set the C flag (V is always cleared at this point) which tells a snippet to push only the high byte
|
||||
odd_save dfb $00,$00,$00 ; The odd exit 3-byte sequence is always stashed here
|
||||
l_is_jmp
|
||||
rep #$20 ; Back to 16-bit mode (carry was set above)
|
||||
; sec ; Set the C flag (V is always cleared at this point) which tells a snippet to push only the high byte
|
||||
dfb $4C ; Expect a JMP instruction
|
||||
odd_high_save dfb $00,$00 ; The high 2 bytes of the 3-byte code field sequence is always stashed here
|
||||
|
||||
; Special epilogue: skip a number of bytes and jump back into the code field. This is useful for
|
||||
; large, floating panels in the attract mode of a game, or to overlay solid
|
||||
|
@ -227,73 +240,95 @@ epilogue_1 tsc
|
|||
; its passed state, because having the carry bit clear prevents evaluation of
|
||||
; the V bit.
|
||||
;
|
||||
; Snippet Samples:
|
||||
; In order to improve performance, especially for two-layer tiles + sprites, the
|
||||
; snippet code has a fixed structure so that the constant DATA and MASK values
|
||||
; always exist in the same location, regarless of the tile type. The
|
||||
; tradeoff is that there is a different entry point into the snippet based on the
|
||||
; tile type, but that is significantly cheaper to lookup and patch into the code
|
||||
; field JMP instruction than it is to rebuild 20+ bytes of code each time.
|
||||
;
|
||||
; Standard Two-level Mix (23 bytes)
|
||||
; There are different snippet templates + offset tables based on the EngineMode
|
||||
;
|
||||
; Optimal = 18 cycles (LDA/AND/ORA/PHA/JMP)
|
||||
; 16-bit write = 20 cycles
|
||||
; 8-bit low = 28 cycles
|
||||
; 8-bit high = 27 cycles
|
||||
; EngineMode
|
||||
;
|
||||
; start lda (00),y ; 6
|
||||
; and #MASK ; 3
|
||||
; ora #DATA ; 3 = 12 cycles to load the data
|
||||
; bcs alt_exit ; 2/3
|
||||
; pha ; 4
|
||||
; out jmp next ; 3 Fast-path completes in 5 additional cycles
|
||||
; alt_exit jmp jmp_rtn ; 3
|
||||
; ENGINE_MODE_TWO_LAYER NO
|
||||
; ENGINE_MODE_DYN_TILES NO
|
||||
;
|
||||
; Snippet Template
|
||||
; None.
|
||||
;
|
||||
; For dynamic masked tiles, we re-write bytes 2 - 8 as this, which mostly
|
||||
; avoids an execution speed pentaly for having to fill in the two extra bytes
|
||||
; with an instruction
|
||||
; ENGINE_MODE_TWO_LAYER YES
|
||||
; ENGINE_MODE_DYN_TILES NO
|
||||
;
|
||||
; start lda (00),y ; 6
|
||||
; and $80,x ; 5
|
||||
; ora $00,x ; 5 = 16 cycles to load the data
|
||||
; bcs alt_exit ; 2/3
|
||||
; pha
|
||||
; ...
|
||||
; Snippet Template
|
||||
;
|
||||
; A theoretical exception handler that performed a full 3-level blend would be
|
||||
; ds 4
|
||||
; lda (00),y <-- Single Entry Point
|
||||
; and #MASK <-- Mask is always at byte 8
|
||||
; ora #DATA <-- Data is always at byte 11
|
||||
; bcs _alt
|
||||
; pha
|
||||
; jmp NEXT
|
||||
; _alt jmp RTN
|
||||
;
|
||||
; start lda 0,s
|
||||
; and [00],y
|
||||
; ora (00),y
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
; bcs alt_exit
|
||||
; pha ; 4
|
||||
; out brl next ; 4 Fast-path completes in 5 additional cycles
|
||||
; ENGINE_MODE_TWO_LAYER NO
|
||||
; ENGINE_MODE_DYN_TILES YES
|
||||
;
|
||||
; alt_exit bvs r_edge ; 2/3
|
||||
; clc ; 2
|
||||
; brl l_jmp_rtn ; 3
|
||||
; r_edge rep #$41
|
||||
; brl r_jmp_rtn ; 3
|
||||
; Snippet Template
|
||||
;
|
||||
; ds 4
|
||||
; lda 00,x <-- Single Entry Point
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
; bcs _alt
|
||||
; pha
|
||||
; jmp NEXT
|
||||
; _alt jmp RTN
|
||||
;
|
||||
; ENGINE_MODE_TWO_LAYER YES
|
||||
; ENGINE_MODE_DYN_TILES YES
|
||||
;
|
||||
; Snippet Template
|
||||
;
|
||||
; lda (00),y <-- Entry Point 1
|
||||
; and $80,x
|
||||
; ora $00,x <-- Entry Point 2 (Change this word to "lda (00),y" or "lda 00,x", or "ora 00,x" depending on combination)
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
; bcs _alt
|
||||
; _16bit pha
|
||||
; jmp NEXT
|
||||
; db 1 <--- Entry Point 3 (opcode for an LDA #DATA instruction)
|
||||
; lda (00),y <--- Entry Point 4 (sneak this in here to avoid extra branch)
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; bcc _16bit
|
||||
; _alt jmp RTN (29 bytes)
|
||||
;
|
||||
; Note that the code that's assembled in these snippets is just a template. Every routine that utilizes
|
||||
; an exception handler *MUST* patch up the routines. There are different routines based on the Engine Mode.
|
||||
;
|
||||
; The LDA (00),y opcodes have a fixed operand, but the dynamic tile instructions are determined by the
|
||||
; dynamic tile id and must be set each time.
|
||||
|
||||
; Each snippet is provided 32 bytes of space. The constant code is filled in from the end and
|
||||
; it is the responsibility of the code that fills in the hander to create valid program in the
|
||||
; first 23 bytes are available to be manipulated.
|
||||
;
|
||||
; Note that the code that's assembled in the first bytes of these snippets is just an example. Every
|
||||
; routine that created an exception handler *MUST* write a full set of instructions since there is
|
||||
; no guarantee of what was written previously.
|
||||
ds \,$00 ; pad to the next page boundary
|
||||
]index equ 0
|
||||
snippets lup 82
|
||||
ds 2 ; space for all exception handlers
|
||||
and #$0000 ; the mask operand will be set when the tile is drawn
|
||||
ora #$0000 ; the data operand will be set when the tile is drawn
|
||||
ds 15 ; extra padding
|
||||
|
||||
bcs :byte ; if C = 0, just push the data and return
|
||||
pha ; 1 byte
|
||||
jmp loop+3+{3*]index}-base ; 3 bytes
|
||||
:byte jmp jmp_rtn-base ; 3 bytes
|
||||
lda ({{81-]index}*2}),y ; 0: Pre-set the LDA (XX),y instructions
|
||||
and $80,x ; 2: The direct page instructions are placeholders and get overwritten
|
||||
ora $00,x ; 4: This gets patched out often
|
||||
and #$0000 ; 6: the mask operand will be set when the tile is drawn
|
||||
ora #$0000 ; 9: the data operand will be set when the tile is drawn
|
||||
bcs :byte ; 12: if C = 0, just push the data and return
|
||||
:word pha ; 14:
|
||||
jmp loop+3+{3*]index}-base ; 15: Return address offset within the code field
|
||||
db $A9 ; 18: LDA #DATA opcode
|
||||
lda ({{81-]index}*2}),y ; 19: Pre-set the LDA (XX),y instructions
|
||||
and $80,x ; 21:
|
||||
ora $00,x ; 23:
|
||||
bcc :word ; 25:
|
||||
:byte jmp jmp_rtn-base ; 27:
|
||||
ds 2 ; 30: Padding to make a full 32 bytes
|
||||
]index equ ]index+1
|
||||
--^
|
||||
top
|
|
@ -72,7 +72,7 @@ Counter equ tmp3
|
|||
rts
|
||||
|
||||
|
||||
; Patch an 8-bit or 16-bit valueS into the bank. These are a set up unrolled loops to
|
||||
; Patch an 8-bit or 16-bit valueS into the bank. These are set up as unrolled loops to
|
||||
; quickly patch in a constant value, or a value from an array into a given set of
|
||||
; templates.
|
||||
;
|
||||
|
@ -87,14 +87,14 @@ Counter equ tmp3
|
|||
; A = value
|
||||
;
|
||||
; Set M to 0 or 1
|
||||
SetConst ; Need a blank line here, otherwise the :tbl local variable resolveds backwards
|
||||
jmp (:tbl,x)
|
||||
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09
|
||||
da :bottom-12,:bottom-15,:bottom-18,:bottom-21
|
||||
da :bottom-24,:bottom-27,:bottom-30,:bottom-33
|
||||
da :bottom-36,:bottom-39,:bottom-42,:bottom-45
|
||||
da :bottom-48
|
||||
:top sta $F000,y
|
||||
SetConst mac
|
||||
jmp (dispTbl,x)
|
||||
dispTbl da bottom-00,bottom-03,bottom-06,bottom-09
|
||||
da bottom-12,bottom-15,bottom-18,bottom-21
|
||||
da bottom-24,bottom-27,bottom-30,bottom-33
|
||||
da bottom-36,bottom-39,bottom-42,bottom-45
|
||||
da bottom-48
|
||||
sta $F000,y
|
||||
sta $E000,y
|
||||
sta $D000,y
|
||||
sta $C000,y
|
||||
|
@ -110,7 +110,8 @@ SetConst ; Need a blank line here, ot
|
|||
sta $2000,y
|
||||
sta $1000,y
|
||||
sta: $0000,y
|
||||
:bottom rts
|
||||
bottom
|
||||
<<<
|
||||
|
||||
; SetDPAddrs
|
||||
;
|
||||
|
@ -244,8 +245,8 @@ BuildBank
|
|||
plb
|
||||
plb
|
||||
|
||||
; Change the patched value to one of DP_ENTRY, TWO_LYR_ENTRY or ONE_LYR_ENTRY based on the capabilities
|
||||
; that the engine needs.
|
||||
; Change the patched value to one of BANK_ENTRY, DP_ENTRY, TWO_LYR_ENTRY or ONE_LYR_ENTRY based
|
||||
; on the capabilities that the engine needs.
|
||||
|
||||
lda #DP_ENTRY
|
||||
sta :entryOffset
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
; A simple helper function that fills in all of the opcodes of a tile with the PEA opcode. This is
|
||||
; a separate functino because we can often just update the tile data if we know the opcodes are already
|
||||
; set. When we have to fill the opcodes, this function is used
|
||||
_TBFillPEAOpcode
|
||||
sep #$20
|
||||
lda #$F4
|
||||
]line equ 0
|
||||
lup 8
|
||||
sta: $0000+{]line*$1000},y
|
||||
sta: $0003+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
; Copy tile data into the direct page compositing buffer. The main reason to do this in full passes is
|
||||
; because we can avoid needing to use both the X and Y registers during the compositing process and
|
||||
; reserve Y to hold the code field address.
|
||||
;
|
||||
; Also, we can get away with not setting the bank register, this is a wash in terms of speed, but results
|
||||
; in simpler, more composable subroutines
|
||||
_TBCopyTileDataAndMaskToCBuff
|
||||
jsr _TBCopyTileDataToCBuff
|
||||
jmp _TBCopyTileMaskToCBuff
|
||||
|
||||
_TBCopyTileDataAndMaskToCBuffV
|
||||
jsr _TBCopyTileDataToCBuffV
|
||||
jmp _TBCopyTileMaskToCBuffV
|
||||
|
||||
_TBCopyTileDataToCBuff
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldal tiledata+{]line*4},x
|
||||
sta blttmp+{]line*4}
|
||||
|
||||
ldal tiledata+{]line*4}+2,x
|
||||
sta blttmp+{]line*4}+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
_TBCopyTileDataToCBuffV
|
||||
]src equ 7
|
||||
]dest equ 0
|
||||
lup 8
|
||||
ldal tiledata+{]src*4},x
|
||||
sta blttmp+{]dest*4}
|
||||
|
||||
ldal tiledata+{]src*4}+2,x
|
||||
sta blttmp+{]dest*4}+2
|
||||
]src equ ]src-1
|
||||
]dest equ ]dest+1
|
||||
--^
|
||||
rts
|
||||
|
||||
; Copy tile mask data into the direct page compositing buffer.
|
||||
_TBCopyTileMaskToCBuff
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldal tiledata+{]line*4}+32,x
|
||||
sta blttmp+{]line*4}+32
|
||||
|
||||
ldal tiledata+{]line*4}+32+2,x
|
||||
sta blttmp+{]line*4}+32+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
_TBCopyTileMaskToCBuffV
|
||||
]src equ 7
|
||||
]dest equ 0
|
||||
lup 8
|
||||
ldal tiledata+{]src*4}+32,x
|
||||
sta blttmp+{]dest*4}+32
|
||||
|
||||
ldal tiledata+{]src*4}+32+2,x
|
||||
sta blttmp+{]dest*4}+32+2
|
||||
]src equ ]src-1
|
||||
]dest equ ]dest+1
|
||||
--^
|
||||
rts
|
||||
|
||||
; Tile 0 specializations
|
||||
; _TBConstTile
|
||||
;
|
||||
; A specialized routine that fills in a tile with a single constant value. It's intended to be used to
|
||||
; fill in solid colors, so there are no specialized horizontal or verical flipped variants
|
||||
_TBConstTileX
|
||||
lda #0
|
||||
sta: $0001,y
|
||||
sta: $0004,y
|
||||
sta $1001,y
|
||||
sta $1004,y
|
||||
sta $2001,y
|
||||
sta $2004,y
|
||||
sta $3001,y
|
||||
sta $3004,y
|
||||
sta $4001,y
|
||||
sta $4004,y
|
||||
sta $5001,y
|
||||
sta $5004,y
|
||||
sta $6001,y
|
||||
sta $6004,y
|
||||
sta $7001,y
|
||||
sta $7004,y
|
||||
plb
|
||||
rts
|
||||
|
||||
_TBConstTileSlow0
|
||||
tax
|
||||
jsr _TBFillPEAOpcode
|
||||
jmp _TBConstTileX
|
||||
|
||||
_TBConstTileDataToDP2
|
||||
]line equ 0
|
||||
lup 8
|
||||
stz tmp_tile_data+{]line*4}
|
||||
stz tmp_tile_data+{]line*4}+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
|
@ -1,580 +0,0 @@
|
|||
; Collection of functions that deal with tiles. Primarily rendering tile data into
|
||||
; the code fields.
|
||||
;
|
||||
; Tile data can be done faily often, so these routines are performance-sensitive.
|
||||
;
|
||||
; CopyTileConst -- the first 16 tile numbers are reserved and can be used
|
||||
; to draw a solid tile block
|
||||
; CopyTileLinear -- copies the tile data from the tile bank in linear order, e.g.
|
||||
; 32 consecutive bytes are copied
|
||||
|
||||
; _RenderTile
|
||||
;
|
||||
; A high-level function that takes a 16-bit tile descriptor and dispatched to the
|
||||
; appropriate tile copy routine based on the descriptor flags
|
||||
;
|
||||
; Bit 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
|
||||
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
; |xx|xx|FF|MM|DD|VV|HH| | | | | | | | | |
|
||||
; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
; \____/ | | | | | \________________________/
|
||||
; | | | | | | Tile ID (0 to 511)
|
||||
; | | | | | |
|
||||
; | | | | | +-- H : Flip tile horizontally
|
||||
; | | | | +----- V : Flip tile vertically
|
||||
; | | | +-------- D : Render as a Dynamic Tile (Tile ID < 32, V and H have no effect)
|
||||
; | | +----------- M : Apply tile mask
|
||||
; | +-------------- F : Overlay a fringe tile
|
||||
; +------------------- Reserved (must be zero)
|
||||
;
|
||||
; Each logical tile (corresponding to each Tile ID) actually takes up 128 bytes of memory in the
|
||||
; tile bank
|
||||
;
|
||||
; +0 : 32 bytes of tile data
|
||||
; +32 : 32 bytes of tile mask
|
||||
; +64 : 32 bytes of horizontally flipped tile data
|
||||
; +96 : 32 bytes of horizontally flipped tile mask
|
||||
;
|
||||
; It is simply too slow to try to horizontally reverse the pixel data on the fly. This still allows
|
||||
; for up to 512 tiles to be stored in a single bank, which should be sufficient.
|
||||
;
|
||||
; Given an address to a Tile Store record, dispatch to the appropriate tile renderer. The Tile
|
||||
; Store record contains all of the low-level information that's needed to call the renderer.
|
||||
;
|
||||
; There are two execution paths that are handled here. First, if there is no sprite, then
|
||||
; the tile data is read directly and written into the code field in a single pass. If there
|
||||
; are sprites that overlap the tile, then the sprite data is combined with the tile data
|
||||
; and written to a temporary direct page buffer. If
|
||||
;
|
||||
; This routine sets the direct page register to the second page since we use that space to
|
||||
; build and cache tile and sprite data, when necessary
|
||||
|
||||
_RenderTile2
|
||||
lda TileStore+TS_SPRITE_FLAG,x ; This is a bitfield of all the sprites that intersect this tile, only care if non-zero or not
|
||||
bne do_dirty_sprite
|
||||
|
||||
; Handle the non-sprite tile blit
|
||||
CopyNoSprites
|
||||
sep #$20
|
||||
lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line
|
||||
pha ; and put on the stack for later
|
||||
|
||||
; lda TileStore+TS_BASE_ADDR+1,x ; load the base address of the code field ($0000 or $8000)
|
||||
; sta _BASE_ADDR+1 ; so we can get by just copying the high byte
|
||||
rep #$20
|
||||
|
||||
lda TileStore+TS_BASE_TILE_DISP,x ; Get the address of the renderer for this tile
|
||||
stal :tiledisp+1
|
||||
|
||||
lda TileStore+TS_TILE_ID,x
|
||||
sta _TILE_ID ; Some tile blitters need to get the tile descriptor
|
||||
|
||||
ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field
|
||||
lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated)
|
||||
pha
|
||||
|
||||
lda TileStore+TS_WORD_OFFSET,x
|
||||
plx
|
||||
plb ; set the bank to the code field that will be updated
|
||||
|
||||
; B is set to the correct code field bank
|
||||
; A is set to the tile word offset (0 through 80 in steps of 4)
|
||||
; Y is set to the top-left address of the tile in the code field
|
||||
; X is set to the address of the tile data
|
||||
|
||||
:tiledisp jmp $0000 ; render the tile
|
||||
|
||||
; The sprite code is just responsible for quickly copying all of the sprite data
|
||||
; into the direct page temp area.
|
||||
|
||||
do_dirty_sprite
|
||||
pei TileStoreBankAndTileDataBank ; Special value that has the TileStore bank in LSB and TileData bank in MSB
|
||||
plb
|
||||
|
||||
; Cache a couple of values into the direct page that are used across all copy routines
|
||||
|
||||
lda TileStore+TS_TILE_ADDR,y ; load the address of this tile's data (pre-calculated)
|
||||
sta tileAddr
|
||||
|
||||
ldx TileStore+TS_VBUFF_ADDR_COUNT,y
|
||||
jmp (dirty_sprite_dispatch,x)
|
||||
dirty_sprite_dispatch
|
||||
da CopyNoSprites
|
||||
da CopyOneSprite
|
||||
da CopyTwoSprites
|
||||
da CopyThreeSprites
|
||||
da CopyFourSprites ; MAX, don't bother with more than 4 sprites per tile
|
||||
|
||||
; We can optimize later, for now just copy the sprite data and mask into its own
|
||||
; direct page buffer and combine with the tile data later
|
||||
;
|
||||
; We set up direct page pointers to the mask bank and use the bank register for the
|
||||
; data.
|
||||
CopyFourSprites
|
||||
lda TileStore+TS_VBUFF_ADDR_0,y
|
||||
sta spriteIdx
|
||||
lda TileStore+TS_VBUFF_ADDR_1,y
|
||||
sta spriteIdx+4
|
||||
lda TileStore+TS_VBUFF_ADDR_2,y
|
||||
sta spriteIdx+8
|
||||
lda TileStore+TS_VBUFF_ADDR_3,y
|
||||
sta spriteIdx+12
|
||||
|
||||
; Copy three sprites into a temporary direct page buffer
|
||||
LDA_IL equ $A7 ; lda [dp]
|
||||
LDA_ILY equ $B7 ; lda [dp],y
|
||||
AND_IL equ $27 ; and [dp]
|
||||
AND_ILY equ $37 ; and [dp],y
|
||||
|
||||
CopyThreeSprites
|
||||
lda TileStore+TS_VBUFF_ADDR_0,y
|
||||
sta spriteIdx
|
||||
lda TileStore+TS_VBUFF_ADDR_1,y
|
||||
sta spriteIdx+4
|
||||
lda TileStore+TS_VBUFF_ADDR_2,y
|
||||
sta spriteIdx+8
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldy #]line*SPRITE_PLANE_SPAN
|
||||
lda (spriteIdx+8),y
|
||||
db AND_ILY,spriteIdx+4 ; Can't use long indirect inside LUP because of ']'
|
||||
ora (spriteIdx+4),y
|
||||
db AND_ILY,spriteIdx+0
|
||||
ora (spriteIdx+0),y
|
||||
sta tmp_sprite_data+{]line*4}
|
||||
|
||||
db LDA_ILY,spriteIdx+8
|
||||
db AND_ILY,spriteIdx+4
|
||||
db AND_ILY,spriteIdx+0
|
||||
sta tmp_sprite_mask+{]line*4}
|
||||
|
||||
ldy #]line*SPRITE_PLANE_SPAN+2
|
||||
lda (spriteIdx+8),y
|
||||
db AND_ILY,spriteIdx+4
|
||||
ora (spriteIdx+4),y
|
||||
db AND_ILY,spriteIdx+0
|
||||
ora (spriteIdx+0),y
|
||||
sta tmp_sprite_data+{]line*4}+2
|
||||
|
||||
db LDA_ILY,spriteIdx+8
|
||||
db AND_ILY,spriteIdx+4
|
||||
db AND_ILY,spriteIdx+0
|
||||
sta tmp_sprite_mask+{]line*4}+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
; jmp FinishTile
|
||||
|
||||
; Copy two sprites into a temporary direct page buffer
|
||||
CopyTwoSprites
|
||||
lda TileStore+TS_VBUFF_ADDR_0,y
|
||||
sta spriteIdx
|
||||
lda TileStore+TS_VBUFF_ADDR_1,y
|
||||
sta spriteIdx+4
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldy #]line*SPRITE_PLANE_SPAN
|
||||
lda (spriteIdx+4),y
|
||||
db AND_ILY,spriteIdx+0
|
||||
ora (spriteIdx+0),y
|
||||
sta tmp_sprite_data+{]line*4}
|
||||
|
||||
db LDA_ILY,spriteIdx+4
|
||||
db AND_ILY,spriteIdx+0
|
||||
sta tmp_sprite_mask+{]line*4}
|
||||
|
||||
ldy #]line*SPRITE_PLANE_SPAN+2
|
||||
lda (spriteIdx+4),y
|
||||
db AND_ILY,spriteIdx+0
|
||||
ora (spriteIdx+0),y
|
||||
sta tmp_sprite_data+{]line*4}+2
|
||||
|
||||
db LDA_ILY,spriteIdx+4
|
||||
db AND_ILY,spriteIdx+0
|
||||
sta tmp_sprite_mask+{]line*4}+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
; jmp FinishTile
|
||||
|
||||
CopyOneSprite
|
||||
clc
|
||||
lda TileStore+TS_VBUFF_ADDR_0,y
|
||||
sta spriteIdx
|
||||
adc #2
|
||||
sta spriteIdx+4
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
; ldal tiledata,x
|
||||
; and [spriteIdx]
|
||||
; ora (spriteIdx)
|
||||
; sta tmp_sprite_data+{]line*4}
|
||||
|
||||
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta tmp_sprite_data+{]line*4}
|
||||
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta tmp_sprite_data+{]line*4}+2
|
||||
|
||||
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta tmp_sprite_mask+{]line*4}
|
||||
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta tmp_sprite_mask+{]line*4}+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
; jmp FinishTile
|
||||
|
||||
; Reference all of the tile rendering subroutines defined in the TileXXXXX files. Each file defines
|
||||
; 8 entry points:
|
||||
;
|
||||
; One set for normal, horizontally flipped, vertically flipped and hors & vert flipped.
|
||||
; A second set that are optimized for when EngineMode has BG1 disabled.
|
||||
TileProcs dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 00000 : normal tiles
|
||||
dw _TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00 ; 00001 : dynamic tiles
|
||||
dw _TBMaskedTile_00,_TBMaskedTile_0H,_TBMaskedTile_V0,_TBMaskedTile_VH ; 00010 : masked normal tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00 ; 00011 : masked dynamic tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
||||
|
||||
; Fringe tiles not supported yet, so just repeat the block from above
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 00100 : fringed normal tiles
|
||||
dw _TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00 ; 00101 : fringed dynamic tiles
|
||||
dw _TBMaskedTile_00,_TBMaskedTile_0H,_TBMaskedTile_V0,_TBMaskedTile_VH ; 00110 : fringed masked normal tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00 ; 00111 : fringed masked dynamic tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
||||
|
||||
; High-priority tiles without a sprite in front of them are just normal tiles. Repeat the top half
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 01000 : high-priority normal tiles
|
||||
dw _TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00 ; 01001 : high-priority dynamic tiles
|
||||
dw _TBMaskedTile_00,_TBMaskedTile_0H,_TBMaskedTile_V0,_TBMaskedTile_VH ; 01010 : high-priority masked normal tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00 ; 01011 : high-priority masked dynamic tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
||||
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 01100 : high-priority fringed normal tiles
|
||||
dw _TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00 ; 01101 : high-priority fringed dynamic tiles
|
||||
dw _TBMaskedTile_00,_TBMaskedTile_0H,_TBMaskedTile_V0,_TBMaskedTile_VH ; 01110 : high-priority fringed masked normal tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00 ; 01111 : high-priority fringed masked dynamic tiles
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
||||
|
||||
; Here are all the sprite variants of the tiles
|
||||
dw _TBSolidSpriteTile_00,_TBSolidSpriteTile_0H
|
||||
dw _TBSolidSpriteTile_V0,_TBSolidSpriteTile_VH ; 10000 : normal tiles w/sprite
|
||||
dw _TBDynamicSpriteTile_00,_TBDynamicSpriteTile_00
|
||||
dw _TBDynamicSpriteTile_00,_TBDynamicSpriteTile_00 ; 10001 : dynamic tiles w/sprite
|
||||
dw _TBMaskedSpriteTile_00,_TBMaskedSpriteTile_0H
|
||||
dw _TBMaskedSpriteTile_V0,_TBMaskedSpriteTile_VH ; 10010 : masked normal tiles w/sprite
|
||||
dw _TBDynamicMaskedSpriteTile_00,_TBDynamicMaskedSpriteTile_00
|
||||
dw _TBDynamicMaskedSpriteTile_00,_TBDynamicMaskedSpriteTile_00 ; 10011 : masked dynamic tiles w/sprite
|
||||
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10100 : fringed normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10101 : fringed dynamic tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10110 : fringed masked normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10111 : fringed masked dynamic tiles w/sprite
|
||||
|
||||
dw _TBSolidPrioritySpriteTile_00,_TBSolidPrioritySpriteTile_0H,
|
||||
dw _TBSolidPrioritySpriteTile_V0,_TBSolidPrioritySpriteTile_VH ; 11000 : high-priority normal tiles w/sprite
|
||||
dw _TBDynamicPrioritySpriteTile_00,_TBDynamicPrioritySpriteTile_00
|
||||
dw _TBDynamicPrioritySpriteTile_00,_TBDynamicPrioritySpriteTile_00 ; 11001 : high-priority dynamic tiles w/sprite
|
||||
dw _TBMaskedPrioritySpriteTile_00,_TBMaskedPrioritySpriteTile_0H
|
||||
dw _TBMaskedPrioritySpriteTile_V0,_TBMaskedPrioritySpriteTile_VH ; 11010 : high-priority masked normal tiles w/sprite
|
||||
dw _TBDynamicMaskedPrioritySpriteTile_00,_TBDynamicMaskedPrioritySpriteTile_00
|
||||
dw _TBDynamicMaskedPrioritySpriteTile_00,_TBDynamicMaskedPrioritySpriteTile_00 ; 11011 : high-priority masked dynamic tiles w/sprite
|
||||
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11100 : high-priority fringed normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11101 : high-priority fringed dynamic tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11110 : high-priority fringed masked normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11111 : high-priority fringed masked dynamic tiles w/sprite
|
||||
|
||||
; _TBConstTile
|
||||
;
|
||||
; A specialized routine that fills in a tile with a single constant value. It's intended to be used to
|
||||
; fill in solid colors, so there are no specialized horizontal or verical flipped variants
|
||||
_TBConstTile
|
||||
sta: $0001,y
|
||||
sta: $0004,y
|
||||
sta $1001,y
|
||||
sta $1004,y
|
||||
sta $2001,y
|
||||
sta $2004,y
|
||||
sta $3001,y
|
||||
sta $3004,y
|
||||
sta $4001,y
|
||||
sta $4004,y
|
||||
sta $5001,y
|
||||
sta $5004,y
|
||||
sta $6001,y
|
||||
sta $6004,y
|
||||
sta $7001,y
|
||||
sta $7004,y
|
||||
jmp _TBFillPEAOpcode
|
||||
|
||||
ClearTile
|
||||
and #$00FF
|
||||
ora #$4800
|
||||
sta: $0004,y
|
||||
sta $1004,y
|
||||
sta $2004,y
|
||||
sta $3004,y
|
||||
sta $4004,y
|
||||
sta $5004,y
|
||||
sta $6004,y
|
||||
sta $7004,y
|
||||
inc
|
||||
inc
|
||||
sta: $0001,y
|
||||
sta $1001,y
|
||||
sta $2001,y
|
||||
sta $3001,y
|
||||
sta $4001,y
|
||||
sta $5001,y
|
||||
sta $6001,y
|
||||
sta $7001,y
|
||||
|
||||
sep #$20
|
||||
lda #$B1 ; This is a special case where we can set all the words to LDA (DP),y
|
||||
sta: $0000,y
|
||||
sta: $0003,y
|
||||
sta $1000,y
|
||||
sta $1003,y
|
||||
sta $2000,y
|
||||
sta $2003,y
|
||||
sta $3000,y
|
||||
sta $3003,y
|
||||
sta $4000,y
|
||||
sta $4003,y
|
||||
sta $5000,y
|
||||
sta $5003,y
|
||||
sta $6000,y
|
||||
sta $6003,y
|
||||
sta $7000,y
|
||||
sta $7003,y
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
; CopyBG0Tile
|
||||
;
|
||||
; A low-level function that copies 8x8 tiles directly into the code field space.
|
||||
;
|
||||
; A = Tile ID (0 - 511)
|
||||
; X = Tile column (0 - 40)
|
||||
; Y = Tile row (0 - 25)
|
||||
_CopyBG0Tile
|
||||
phb ; save the current bank
|
||||
phx ; save the original x-value
|
||||
pha ; save the tile ID
|
||||
|
||||
tya ; lookup the address of the virtual line (y * 8)
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl ; x2 because the table contains words, not
|
||||
tay
|
||||
|
||||
sep #$20 ; set the bank register
|
||||
lda BTableHigh,y
|
||||
pha ; save for a few instruction
|
||||
rep #$20
|
||||
|
||||
txa
|
||||
asl ; there are two columns per tile, so multiple by 4
|
||||
asl ; asl will clear the carry bit
|
||||
tax
|
||||
|
||||
lda BTableLow,y
|
||||
sta _BASE_ADDR ; Used in masked tile renderer
|
||||
clc
|
||||
adc Col2CodeOffset+2,x ; Get the right edge (which is the lower physical address)
|
||||
tay
|
||||
|
||||
plb ; set the bank
|
||||
pla ; pop the tile ID
|
||||
; jsr _RenderTile
|
||||
|
||||
:exit
|
||||
plx ; pop the x-register
|
||||
plb ; restore the data bank and return
|
||||
rts
|
||||
|
||||
|
||||
; CopyBG1Tile
|
||||
;
|
||||
; A low-level function that copies 8x8 tiles directly into the BG1 data buffer.
|
||||
;
|
||||
; A = Tile ID (0 - 511)
|
||||
; X = Tile column (0 - 40)
|
||||
; Y = Tile row (0 - 25)
|
||||
_CopyBG1Tile
|
||||
phb ; save the current bank
|
||||
phx ; save the original x-value
|
||||
pha ; save the tile ID
|
||||
|
||||
tya ; lookup the address of the virtual line (y * 8)
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
tay
|
||||
|
||||
txa
|
||||
asl
|
||||
asl ; 4 bytes per tile column
|
||||
clc
|
||||
adc BG1YTable,y
|
||||
tay
|
||||
|
||||
sep #$20
|
||||
lda BG1DataBank
|
||||
pha
|
||||
plb ; set the bank
|
||||
rep #$20
|
||||
|
||||
pla ; pop the tile ID
|
||||
jsr _RenderTileBG1
|
||||
|
||||
plx ; pop the x-register
|
||||
plb ; restore the data bank and return
|
||||
rts
|
||||
|
||||
; Tile Store that holds tile records which contain all the essential information for rendering
|
||||
; a tile.
|
||||
;
|
||||
; TileStore+TS_TILE_ID : Tile descriptor
|
||||
; TileStore+TS_DIRTY : $0000 is clean, any other value indicated a dirty tile
|
||||
; TileStore+TS_TILE_ADDR : Address of the tile in the tile data buffer
|
||||
; TileStore+TS_CODE_ADDR_LOW : Low word of the address in the code field that receives the tile
|
||||
; TileStore+TS_CODE_ADDR_HIGH : High word of the address in the code field that receives the tile
|
||||
; TileStore+TS_WORD_OFFSET : Logical number of word for this location
|
||||
; TileStore+TS_BASE_ADDR : Copy of BTableAddrLow
|
||||
; TileStore+TS_SCREEN_ADDR : Address on the physical screen corresponding to this tile (for direct rendering)
|
||||
; TileStore+TS_SPRITE_FLAG : A bit field of all sprites that intersect this tile
|
||||
; TileStore+TS_SPRITE_ADDR_1 ; Address of the sprite data that aligns with this tile. These
|
||||
; TileStore+TS_SPRITE_ADDR_2 ; values are 1:1 with the TS_SPRITE_FLAG bits and are not contiguous.
|
||||
; TileStore+TS_SPRITE_ADDR_3 ; If the bit position in TS_SPRITE_FLAG is not set, then the value in
|
||||
; TileStore+TS_SPRITE_ADDR_4 ; the TS_SPRITE_ADDR_* field is undefined.
|
||||
; TileStore+TS_SPRITE_ADDR_5
|
||||
; TileStore+TS_SPRITE_ADDR_6
|
||||
; TileStore+TS_SPRITE_ADDR_7
|
||||
; TileStore+TS_SPRITE_ADDR_8
|
||||
; TileStore+TS_SPRITE_ADDR_9
|
||||
; TileStore+TS_SPRITE_ADDR_10
|
||||
; TileStore+TS_SPRITE_ADDR_11
|
||||
; TileStore+TS_SPRITE_ADDR_12
|
||||
; TileStore+TS_SPRITE_ADDR_13
|
||||
; TileStore+TS_SPRITE_ADDR_14
|
||||
; TileStore+TS_SPRITE_ADDR_15
|
||||
; TileStore+TS_SPRITE_ADDR_16
|
||||
|
||||
; To make processing the tile faster, we do them in chunks of eight. This allows the loop to be
|
||||
; unrolled, which means we don't have to keep track of the register value and makes it faster to
|
||||
; clear the dirty tile flag after being processed.
|
||||
; _ApplyTilesUnrolled
|
||||
tdc ; Move to the dedicated direct page for tile rendering
|
||||
clc
|
||||
adc #$100
|
||||
tcd
|
||||
|
||||
phb ; Save the current bank
|
||||
tsc
|
||||
sta tmp0 ; Save it on the direct page
|
||||
bra at_loop
|
||||
|
||||
; The DirtyTiles array and the TileStore information is in the Tile Store bank. Because we
|
||||
; process up to 8 tiles as a time and the tile code sets the bank register to the target
|
||||
; code field bank, we need to restore the bank register each time. So, we pre-push
|
||||
; 8 copies of the TileStore bank onto the stack.
|
||||
|
||||
|
||||
at_exit
|
||||
tdc ; Move back to the original direct page
|
||||
sec
|
||||
sbc #$100
|
||||
tcd
|
||||
|
||||
plb ; Restore the original data bank and return
|
||||
rts
|
||||
dt_base equ $FE ; top of second direct page space
|
||||
|
||||
at_loop
|
||||
lda tmp0
|
||||
tcs
|
||||
|
||||
lda DirtyTileCount ; This is pre-multiplied by 2
|
||||
beq at_exit ; If there are no items, exit
|
||||
|
||||
ldx TileStoreBankDoubled
|
||||
phx
|
||||
phx
|
||||
phx
|
||||
|
||||
cmp #16 ; If there are >= 8 elements, then
|
||||
bcs at_chunk ; do a full chunk
|
||||
|
||||
stz DirtyTileCount ; Otherwise, this pass will handle them all
|
||||
tax
|
||||
jmp (at_table,x)
|
||||
at_table da at_exit,at_one,at_two,at_three
|
||||
da at_four,at_five,at_six,at_seven
|
||||
|
||||
at_chunk sec
|
||||
sbc #16
|
||||
sta DirtyTileCount ; Fall through
|
||||
|
||||
; Because all of the registers get used in the _RenderTile2 subroutine, we
|
||||
; push the values from the DirtyTiles array onto the stack and then pop off
|
||||
; the values as we go
|
||||
|
||||
ldy dt_base ; Reload the base index
|
||||
ldx DirtyTiles+14,y ; Load the TileStore offset
|
||||
stz TileStore+TS_DIRTY,x ; Clear this tile's dirty flag
|
||||
jsr _RenderTile2 ; Draw the tile
|
||||
plb ; Reset the data bank to the TileStore bank
|
||||
|
||||
at_seven
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+12,y
|
||||
stz TileStore+TS_DIRTY,x
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
at_six
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+10,y
|
||||
stz TileStore+TS_DIRTY,x
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
at_five
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+8,y
|
||||
stz TileStore+TS_DIRTY,x
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
at_four
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+6,y
|
||||
stz TileStore+TS_DIRTY,x
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
at_three
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+4,y
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
at_two
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+2,y
|
||||
stz TileStore+TS_DIRTY,x
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
at_one
|
||||
ldy dt_base
|
||||
ldx DirtyTiles+0,y
|
||||
stz TileStore+TS_DIRTY,x
|
||||
jsr _RenderTile2
|
||||
plb
|
||||
|
||||
jmp at_loop
|
|
@ -1,52 +0,0 @@
|
|||
; _TBSolidTile
|
||||
;
|
||||
; Define the addresses of the subroutines that draw the normal and flipped variants of the tiles, both
|
||||
; in the optimized (no second background) and normal cases.
|
||||
;
|
||||
; On entry, the following register values need to be set
|
||||
;
|
||||
; X : address of base tile in the tiledata bank (tileId * 128)
|
||||
; Y : address of the top-left corder of the tile location in the code field
|
||||
; B : set to the code field bank
|
||||
|
||||
_TBSolidTile_00
|
||||
jsr _TBCopyData
|
||||
jmp _TBFillPEAOpcode
|
||||
|
||||
_TBSolidTile_0H
|
||||
jsr _TBCopyData
|
||||
jmp _TBFillPEAOpcode
|
||||
|
||||
_TBSolidTile_V0
|
||||
jsr _TBCopyDataV
|
||||
jmp _TBFillPEAOpcode
|
||||
|
||||
_TBSolidTile_VH
|
||||
jsr _TBCopyDataV
|
||||
jmp _TBFillPEAOpcode
|
||||
|
||||
; Old routines
|
||||
_TBCopyData
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldal tiledata+{]line*4},x
|
||||
sta: $0004+{]line*$1000},y
|
||||
ldal tiledata+{]line*4}+2,x
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
_TBCopyDataV
|
||||
]src equ 7
|
||||
]dest equ 0
|
||||
lup 8
|
||||
ldal tiledata+{]src*4},x
|
||||
sta: $0004+{]dest*$1000},y
|
||||
ldal tiledata+{]src*4}+2,x
|
||||
sta: $0001+{]dest*$1000},y
|
||||
]src equ ]src-1
|
||||
]dest equ ]dest+1
|
||||
--^
|
||||
rts
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
; _TBDynamicTile
|
||||
;
|
||||
; These subroutines fill in the code field with the instructions to render data from the dynamic
|
||||
; code buffer. This is a bit different, because no tile data is manipulated. It is the
|
||||
; responsibiliy of the user of the API to use the CopyTileToDyn subroutine to get data
|
||||
; into the correct location.
|
||||
;
|
||||
; This tile type does not explicitly support horizontal or vertical flipping. An appropriate tile
|
||||
; descriptor should be passed into CopyTileToDyn to put the horizontally or vertically flipped source
|
||||
; data into the dynamic tile buffer
|
||||
_TBDynamicTile_00
|
||||
jsr _TBDynamicData
|
||||
jmp _TBFillLdaDpOpcode
|
||||
|
||||
_TBDynamic
|
||||
ldal TileStore+TS_TILE_ID,x
|
||||
and #$007F
|
||||
ora #$4800
|
||||
|
||||
]line equ 0 ; render the first column
|
||||
lup 8
|
||||
sta: $0004+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
inc ; advance to the next word
|
||||
inc
|
||||
|
||||
]line equ 0 ; render the second column
|
||||
lup 8
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
sep #$20
|
||||
lda #$B5
|
||||
sta: $0000,y
|
||||
sta: $0003,y
|
||||
sta $1000,y
|
||||
sta $1003,y
|
||||
sta $2000,y
|
||||
sta $2003,y
|
||||
sta $3000,y
|
||||
sta $3003,y
|
||||
sta $4000,y
|
||||
sta $4003,y
|
||||
sta $5000,y
|
||||
sta $5003,y
|
||||
sta $6000,y
|
||||
sta $6003,y
|
||||
sta $7000,y
|
||||
sta $7003,y
|
||||
rep #$20
|
||||
|
||||
plb
|
||||
rts
|
||||
; Primitive to render a dynamic tile
|
||||
;
|
||||
; LDA 00,x / PHA where the operand is fixed when the tile is rendered
|
||||
; $B5 $00 $48
|
||||
_TBDynamicData
|
||||
lda _TILE_ID ; Get the original tile descriptor
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
ora #$4800 ; insert the PHA instruction
|
||||
|
||||
]line equ 0 ; render the first column
|
||||
lup 8
|
||||
sta: $0004+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
inc ; advance to the next word
|
||||
inc
|
||||
|
||||
]line equ 0 ; render the second column
|
||||
lup 8
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
|
||||
rts
|
||||
|
||||
; A simple helper function that fill in all of the opcodes of a tile with the LDA dp,x opcode.
|
||||
_TBFillLdaDpOpcode
|
||||
sep #$20
|
||||
lda #$B5
|
||||
sta: $0000,y
|
||||
sta: $0003,y
|
||||
sta $1000,y
|
||||
sta $1003,y
|
||||
sta $2000,y
|
||||
sta $2003,y
|
||||
sta $3000,y
|
||||
sta $3003,y
|
||||
sta $4000,y
|
||||
sta $4003,y
|
||||
sta $5000,y
|
||||
sta $5003,y
|
||||
sta $6000,y
|
||||
sta $6003,y
|
||||
sta $7000,y
|
||||
sta $7003,y
|
||||
rep #$20
|
||||
rts
|
|
@ -1,131 +0,0 @@
|
|||
; _TBMaskedTile
|
||||
;
|
||||
; These tile renderes are for "normal" tiles that also apply their mask data. If the case of the second
|
||||
; background being disabled, the optimized variants are the same as Tile00000
|
||||
;
|
||||
; Y register = address of code field tile
|
||||
; X register = tile address
|
||||
; Accumulator = logical word offset of the tile (0, 2, 4, ..., 82)
|
||||
;
|
||||
; Need to slightly remap these register inputs to save into the direct page cached values
|
||||
_TBMaskedTile_00
|
||||
_TBMaskedTile_0H
|
||||
sta _X_REG ; Save these values as we will need to reload them
|
||||
sty _Y_REG ; at certain points
|
||||
stx _T_PTR
|
||||
|
||||
; Do the left column first
|
||||
|
||||
CopyMaskedWord tiledata+0;tiledata+32+0;$0003
|
||||
CopyMaskedWord tiledata+4;tiledata+32+4;$1003
|
||||
CopyMaskedWord tiledata+8;tiledata+32+8;$2003
|
||||
CopyMaskedWord tiledata+12;tiledata+32+12;$3003
|
||||
CopyMaskedWord tiledata+16;tiledata+32+16;$4003
|
||||
CopyMaskedWord tiledata+20;tiledata+32+20;$5003
|
||||
CopyMaskedWord tiledata+24;tiledata+32+24;$6003
|
||||
CopyMaskedWord tiledata+28;tiledata+32+28;$7003
|
||||
|
||||
; Move the index for the JTableOffset array. This is the same index used for transparent words,
|
||||
; so, if _X_REG is zero, then we would be patching out the last word in the code field with LDA (0),y
|
||||
; and then increment _X_REG by two to patch the next-to-last word in the code field with LDA (2),y
|
||||
|
||||
inc _X_REG
|
||||
inc _X_REG
|
||||
|
||||
; Do the right column
|
||||
|
||||
CopyMaskedWord tiledata+2;tiledata+32+2;$0000
|
||||
CopyMaskedWord tiledata+6;tiledata+32+6;$1000
|
||||
CopyMaskedWord tiledata+10;tiledata+32+10;$2000
|
||||
CopyMaskedWord tiledata+14;tiledata+32+14;$3000
|
||||
CopyMaskedWord tiledata+18;tiledata+32+18;$4000
|
||||
CopyMaskedWord tiledata+22;tiledata+32+22;$5000
|
||||
CopyMaskedWord tiledata+26;tiledata+32+26;$6000
|
||||
CopyMaskedWord tiledata+30;tiledata+32+30;$7000
|
||||
|
||||
rts
|
||||
|
||||
;_TBMaskedTile_0H
|
||||
; sta _X_REG
|
||||
; sty _Y_REG
|
||||
; stx _T_PTR
|
||||
;
|
||||
; CopyMaskedWord tiledata+64+0;tiledata+64+32+0;$0003
|
||||
; CopyMaskedWord tiledata+64+4;tiledata+64+32+4;$1003
|
||||
; CopyMaskedWord tiledata+64+8;tiledata+64+32+8;$2003
|
||||
; CopyMaskedWord tiledata+64+12;tiledata+64+32+12;$3003
|
||||
; CopyMaskedWord tiledata+64+16;tiledata+64+32+16;$4003
|
||||
; CopyMaskedWord tiledata+64+20;tiledata+64+32+20;$5003
|
||||
; CopyMaskedWord tiledata+64+24;tiledata+64+32+24;$6003
|
||||
; CopyMaskedWord tiledata+64+28;tiledata+64+32+28;$7003
|
||||
;
|
||||
; inc _X_REG
|
||||
; inc _X_REG
|
||||
;
|
||||
; CopyMaskedWord tiledata+64+2;tiledata+64+32+2;$0000
|
||||
; CopyMaskedWord tiledata+64+6;tiledata+64+32+6;$1000
|
||||
; CopyMaskedWord tiledata+64+10;tiledata+64+32+10;$2000
|
||||
; CopyMaskedWord tiledata+64+14;tiledata+64+32+14;$3000
|
||||
; CopyMaskedWord tiledata+64+18;tiledata+64+32+18;$4000
|
||||
; CopyMaskedWord tiledata+64+22;tiledata+64+32+22;$5000
|
||||
; CopyMaskedWord tiledata+64+26;tiledata+64+32+26;$6000
|
||||
; CopyMaskedWord tiledata+64+30;tiledata+64+32+30;$7000
|
||||
;
|
||||
; rts
|
||||
|
||||
_TBMaskedTile_V0
|
||||
_TBMaskedTile_VH
|
||||
sta _X_REG
|
||||
sty _Y_REG
|
||||
stx _T_PTR
|
||||
|
||||
CopyMaskedWord tiledata+0;tiledata+32+0;$7003
|
||||
CopyMaskedWord tiledata+4;tiledata+32+4;$6003
|
||||
CopyMaskedWord tiledata+8;tiledata+32+8;$5003
|
||||
CopyMaskedWord tiledata+12;tiledata+32+12;$4003
|
||||
CopyMaskedWord tiledata+16;tiledata+32+16;$3003
|
||||
CopyMaskedWord tiledata+20;tiledata+32+20;$2003
|
||||
CopyMaskedWord tiledata+24;tiledata+32+24;$1003
|
||||
CopyMaskedWord tiledata+28;tiledata+32+28;$0003
|
||||
|
||||
inc _X_REG
|
||||
inc _X_REG
|
||||
|
||||
CopyMaskedWord tiledata+2;tiledata+32+2;$7000
|
||||
CopyMaskedWord tiledata+6;tiledata+32+6;$6000
|
||||
CopyMaskedWord tiledata+10;tiledata+32+10;$5000
|
||||
CopyMaskedWord tiledata+14;tiledata+32+14;$4000
|
||||
CopyMaskedWord tiledata+18;tiledata+32+18;$3000
|
||||
CopyMaskedWord tiledata+22;tiledata+32+22;$2000
|
||||
CopyMaskedWord tiledata+26;tiledata+32+26;$1000
|
||||
CopyMaskedWord tiledata+30;tiledata+32+30;$0000
|
||||
|
||||
rts
|
||||
|
||||
;_TBMaskedTile_VH
|
||||
; sta _X_REG
|
||||
; sty _Y_REG
|
||||
; stx _T_PTR
|
||||
;
|
||||
; CopyMaskedWord tiledata+64+0;tiledata+64+32+0;$7003
|
||||
; CopyMaskedWord tiledata+64+4;tiledata+64+32+4;$6003
|
||||
; CopyMaskedWord tiledata+64+8;tiledata+64+32+8;$5003
|
||||
; CopyMaskedWord tiledata+64+12;tiledata+64+32+12;$4003
|
||||
; CopyMaskedWord tiledata+64+16;tiledata+64+32+16;$3003
|
||||
; CopyMaskedWord tiledata+64+20;tiledata+64+32+20;$2003
|
||||
; CopyMaskedWord tiledata+64+24;tiledata+64+32+24;$1003
|
||||
; CopyMaskedWord tiledata+64+28;tiledata+64+32+28;$0003
|
||||
;
|
||||
; inc _X_REG
|
||||
; inc _X_REG
|
||||
;
|
||||
; CopyMaskedWord tiledata+64+2;tiledata+64+32+2;$7000
|
||||
; CopyMaskedWord tiledata+64+6;tiledata+64+32+6;$6000
|
||||
; CopyMaskedWord tiledata+64+10;tiledata+64+32+10;$5000
|
||||
; CopyMaskedWord tiledata+64+14;tiledata+64+32+14;$4000
|
||||
; CopyMaskedWord tiledata+64+18;tiledata+64+32+18;$3000
|
||||
; CopyMaskedWord tiledata+64+22;tiledata+64+32+22;$2000
|
||||
; CopyMaskedWord tiledata+64+26;tiledata+64+32+26;$1000
|
||||
; CopyMaskedWord tiledata+64+30;tiledata+64+32+30;$0000
|
||||
;
|
||||
; rts
|
|
@ -1,122 +0,0 @@
|
|||
; _TBDynamicMaskTile
|
||||
;
|
||||
; Insert a code sequence to mask the dynamic tile against the background. This is quite a slow process because
|
||||
; every word needs to be handled with a JMP exception; but it looks good!
|
||||
_TBDynamicMaskTile_00
|
||||
jsr _TBDynamicDataAndMask
|
||||
jmp _TBFillJMPOpcode
|
||||
|
||||
; A = dynamic tile id (must be <32)
|
||||
_TBDynamicDataAndMask
|
||||
sta _X_REG ; Cache some column values derived from _X_REG
|
||||
tax
|
||||
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
|
||||
xba
|
||||
sta _OP_CACHE
|
||||
|
||||
clc
|
||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
sta _JTBL_CACHE
|
||||
|
||||
; We need to do an AND dp|$80,x / ORA dp,x. The opcode values are $35 and $15, respectively.
|
||||
; We pre-calculate the AND opcode with the high bit of the operand set and then, in the macro
|
||||
; perform and EOR #$2080 to covert the opcode and operand in one instruction
|
||||
|
||||
lda _TILE_ID ; Get the original tile descriptor
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
ora #$3580 ; Pre-calc the AND $80,x opcode + operand
|
||||
xba
|
||||
sta _T_PTR ; This is an op to load the dynamic tile data
|
||||
|
||||
CopyMaskedDWord $0003
|
||||
CopyMaskedDWord $1003
|
||||
CopyMaskedDWord $2003
|
||||
CopyMaskedDWord $3003
|
||||
CopyMaskedDWord $4003
|
||||
CopyMaskedDWord $5003
|
||||
CopyMaskedDWord $6003
|
||||
CopyMaskedDWord $7003
|
||||
|
||||
ldx _X_REG
|
||||
clc
|
||||
ldal JTableOffset+2,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
sta _JTBL_CACHE
|
||||
|
||||
lda _OP_CACHE
|
||||
adc #$0200
|
||||
sta _OP_CACHE
|
||||
lda _T_PTR
|
||||
adc #$0200
|
||||
sta _T_PTR
|
||||
|
||||
CopyMaskedDWord $0000
|
||||
CopyMaskedDWord $1000
|
||||
CopyMaskedDWord $2000
|
||||
CopyMaskedDWord $3000
|
||||
CopyMaskedDWord $4000
|
||||
CopyMaskedDWord $5000
|
||||
CopyMaskedDWord $6000
|
||||
CopyMaskedDWord $7000
|
||||
|
||||
rts
|
||||
|
||||
; A simple helper function that fill in all of the opcodes of a tile with the JMP opcode.
|
||||
_TBFillJMPOpcode
|
||||
sep #$20
|
||||
lda #$4C
|
||||
sta: $0000,y
|
||||
sta: $0003,y
|
||||
sta $1000,y
|
||||
sta $1003,y
|
||||
sta $2000,y
|
||||
sta $2003,y
|
||||
sta $3000,y
|
||||
sta $3003,y
|
||||
sta $4000,y
|
||||
sta $4003,y
|
||||
sta $5000,y
|
||||
sta $5003,y
|
||||
sta $6000,y
|
||||
sta $6003,y
|
||||
sta $7000,y
|
||||
sta $7003,y
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
|
||||
; Masked renderer for a dynamic tile. What's interesting about this renderer is that the mask
|
||||
; value is not used directly, but simply indicates if we can use a LDA 0,x / PHA sequence,
|
||||
; a LDA (00),y / PHA, or a JMP to a blended render
|
||||
;
|
||||
; If a dynamic tile is animated, there is the possibility to create a special mask that marks
|
||||
; words of the tile that a front / back / mixed across all frames.
|
||||
;
|
||||
; ]1 : code field offset
|
||||
;
|
||||
; This macro does not set the opcode since they will all be JMP instructions, they can be
|
||||
; filled more efficiently in a separate routine.
|
||||
CopyMaskedDWord MAC
|
||||
|
||||
; Need to fill in the first 6 bytes of the JMP handler with the following code sequence
|
||||
;
|
||||
; lda (00),y
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; bra *+17
|
||||
|
||||
lda _JTBL_CACHE
|
||||
ora #{]1&$F000} ; adjust for the current row offset
|
||||
sta: ]1+1,y
|
||||
|
||||
tax ; This becomes the new address that we use to patch in
|
||||
lda _OP_CACHE
|
||||
sta: $0000,x ; LDA (00),y
|
||||
lda _T_PTR
|
||||
sta: $0002,x ; AND $80,x
|
||||
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||
sta: $0004,x ; ORA $00,x
|
||||
lda #$0F80 ; branch to the prologue (BRA *+17)
|
||||
sta: $0006,x
|
||||
eom
|
|
@ -1,6 +0,0 @@
|
|||
; _TBPriorityTile
|
||||
;
|
||||
; The priority bit allows the tile to be rendered in front of sprites. If there's no sprite
|
||||
; in this tile area, then just fallback to the Tile00000.s implementation
|
||||
_TBPriorityTile dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH
|
||||
dw _TBCopyData,_TBCopyDataH,_TBCopyDataV,_TBCopyDataVH
|
|
@ -1,6 +0,0 @@
|
|||
; _TBPriorityDynamicTile
|
||||
;
|
||||
; The priority bit allows the tile to be rendered in front of sprites. If there's no sprite
|
||||
; in this tile area, then just fallback to the Tile00001.s implementation
|
||||
_TBPriorityDynamicTile dw _TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00
|
||||
dw _TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00,_TBDynamicTile_00
|
|
@ -1,19 +0,0 @@
|
|||
; _TBMaskedPriorityTile
|
||||
;
|
||||
; The priority bit allows the tile to be rendered in front of sprites. If there's no sprite
|
||||
; in this tile area, then just fallback to the Tile00000.s implementation
|
||||
_TBMaskedPriorityTile dw _TBMaskedTile_00,_TBMaskedTile_0H,_TBMaskedTile_V0,_TBMaskedTile_VH
|
||||
dw _TBCopyData,_TBCopyDataH,_TBCopyDataV,_TBCopyDataVH
|
||||
|
||||
; NOTE: Eventually, we want a way to support this use-case
|
||||
;
|
||||
; When the high-priority bit is set for a tile, then the BG0 tile will be rendered behind the BG1 data. In
|
||||
; order to support this, the optional BG1 mask buffer needs to be enabled and *every* word in the tile
|
||||
; becomes a JMP handler (similar to masked dynamic tiles)
|
||||
;
|
||||
; The 8 bytes of code that is generated in the JMP handler is
|
||||
;
|
||||
; lda #tiledata
|
||||
; and [dp],y
|
||||
; ora (dp),y
|
||||
; nop
|
|
@ -1,99 +0,0 @@
|
|||
; _TBSolidSpriteTile
|
||||
;
|
||||
; Renders solid tiles with sprites layered on top of the tile data. Because we need to combine
|
||||
; data from the sprite plane, tile data and write to the code field (which are all in different banks),
|
||||
; there is no way to do everything inline, so a composite tile is created on the fly and written to
|
||||
; a direct page buffer. This direct page buffer is then used to render the tile.
|
||||
_TBSolidSpriteTile_00
|
||||
_TBSolidSpriteTile_0H
|
||||
jsr _TBCopyTileDataToCBuff ; Copy the tile into the compositing buffer (using correct x-register)
|
||||
jsr _TBApplySpriteData ; Overlay the data from the sprite plane (and copy into the code field)
|
||||
jmp _TBFillPEAOpcode ; Fill in the code field opcodes
|
||||
|
||||
_TBSolidSpriteTile_V0
|
||||
_TBSolidSpriteTile_VH
|
||||
jsr _TBCopyTileDataToCBuffV
|
||||
jsr _TBApplySpriteData
|
||||
jmp _TBFillPEAOpcode
|
||||
|
||||
; Fast variation that does not need to set the opcode
|
||||
_TBFastSpriteTile_00
|
||||
_TBFastSpriteTile_0H
|
||||
jsr _TBCopyTileDataToCBuff ; Copy the tile into the compositing buffer
|
||||
jmp _TBApplySpriteData ; Overlay the data form the sprite plane (and copy into the code field)
|
||||
|
||||
_TBFastSpriteTile_V0
|
||||
_TBFastSpriteTile_VH
|
||||
jsr _TBCopyTileDataToCBuffV
|
||||
jmp _TBApplySpriteData
|
||||
|
||||
; Need to update the X-register before calling this
|
||||
_TBApplySpriteData
|
||||
ldx _SPR_X_REG ; set to the unaligned tile block address in the sprite plane
|
||||
]line equ 0
|
||||
lup 8
|
||||
lda blttmp+{]line*4}
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta: $0004+{]line*$1000},y
|
||||
|
||||
lda blttmp+{]line*4}+2
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
_TBApplySpriteDataOne
|
||||
ldx spriteIdx
|
||||
]line equ 0
|
||||
lup 8
|
||||
lda blttmp+{]line*4}
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta: $0004+{]line*$1000},y
|
||||
|
||||
lda blttmp+{]line*4}+2
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
_TBApplySpriteDataTwo
|
||||
]line equ 0
|
||||
lup 8
|
||||
lda blttmp+{]line*4}
|
||||
ldx spriteIdx+2
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
ldx spriteIdx
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta: $0004+{]line*$1000},y
|
||||
|
||||
lda blttmp+{]line*4}+2
|
||||
ldx spriteIdx+2
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
ldx spriteIdx
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
; Copy just the data into the code field from the composite buffer
|
||||
_TBSolidComposite
|
||||
]line equ 0
|
||||
lup 8
|
||||
lda blttmp+{]line*4}
|
||||
sta: $0004+{]line*$1000},y
|
||||
lda blttmp+{]line*4}+2
|
||||
sta: $0001+{]line*$1000},y
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
|
@ -1,211 +0,0 @@
|
|||
; _TBDynamicSpriteTile
|
||||
;
|
||||
; This tile type does not explicitly support horizontal or vertical flipping. An appropriate tile
|
||||
; descriptor should be passed into CopyTileToDyn to put the horizontally or vertically flipped source
|
||||
; data into the dynamic tile buffer
|
||||
_TBDynamicSpriteTile
|
||||
sta _X_REG
|
||||
ldal TileStore+TS_JMP_ADDR,x ; Get the address of the exception handler
|
||||
sta _JTBL_CACHE
|
||||
|
||||
ldal TileStore+TS_TILE_ID,x ; Get the original tile descriptor
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
ora #$B500
|
||||
xba
|
||||
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
|
||||
|
||||
CopyDynWord 0;$0003
|
||||
CopyDynWord 4;$1003
|
||||
CopyDynWord 8;$2003
|
||||
CopyDynWord 12;$3003
|
||||
CopyDynWord 16;$4003
|
||||
CopyDynWord 20;$5003
|
||||
CopyDynWord 24;$6003
|
||||
CopyDynWord 28;$7003
|
||||
|
||||
clc
|
||||
lda _JTBL_CACHE
|
||||
adc #32 ; All the snippets are 32 bytes wide and, since we're
|
||||
sta _JTBL_CACHE ; within one tile, the second column is consecutive
|
||||
|
||||
lda _OP_CACHE
|
||||
adc #$0200 ; Advance to the next word
|
||||
sta _OP_CACHE
|
||||
|
||||
CopyDynWord 2;$0000
|
||||
CopyDynWord 6;$1000
|
||||
CopyDynWord 10;$2000
|
||||
CopyDynWord 14;$3000
|
||||
CopyDynWord 18;$4000
|
||||
CopyDynWord 22;$5000
|
||||
CopyDynWord 26;$6000
|
||||
CopyDynWord 30;$7000
|
||||
|
||||
plb
|
||||
rts
|
||||
|
||||
|
||||
_TBDynamicSpriteTile_00
|
||||
sty _Y_REG ; This is restored in the macro
|
||||
|
||||
sta _X_REG ; Cache some column values derived from _X_REG
|
||||
tax
|
||||
clc
|
||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
sta _JTBL_CACHE
|
||||
|
||||
lda _TILE_ID ; Get the original tile descriptor
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
ora #$B500
|
||||
xba
|
||||
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynSpriteWord {0*SPRITE_PLANE_SPAN};$0003
|
||||
CopyDynSpriteWord {1*SPRITE_PLANE_SPAN};$1003
|
||||
CopyDynSpriteWord {2*SPRITE_PLANE_SPAN};$2003
|
||||
CopyDynSpriteWord {3*SPRITE_PLANE_SPAN};$3003
|
||||
CopyDynSpriteWord {4*SPRITE_PLANE_SPAN};$4003
|
||||
CopyDynSpriteWord {5*SPRITE_PLANE_SPAN};$5003
|
||||
CopyDynSpriteWord {6*SPRITE_PLANE_SPAN};$6003
|
||||
CopyDynSpriteWord {7*SPRITE_PLANE_SPAN};$7003
|
||||
|
||||
ldx _X_REG
|
||||
clc
|
||||
ldal JTableOffset+2,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
sta _JTBL_CACHE
|
||||
|
||||
lda _OP_CACHE
|
||||
adc #$0200
|
||||
sta _OP_CACHE
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynSpriteWord {0*SPRITE_PLANE_SPAN}+2;$0000
|
||||
CopyDynSpriteWord {1*SPRITE_PLANE_SPAN}+2;$1000
|
||||
CopyDynSpriteWord {2*SPRITE_PLANE_SPAN}+2;$2000
|
||||
CopyDynSpriteWord {3*SPRITE_PLANE_SPAN}+2;$3000
|
||||
CopyDynSpriteWord {4*SPRITE_PLANE_SPAN}+2;$4000
|
||||
CopyDynSpriteWord {5*SPRITE_PLANE_SPAN}+2;$5000
|
||||
CopyDynSpriteWord {6*SPRITE_PLANE_SPAN}+2;$6000
|
||||
CopyDynSpriteWord {7*SPRITE_PLANE_SPAN}+2;$7000
|
||||
|
||||
rts
|
||||
|
||||
; Create a masked render based on data in the direct page temporary buffer
|
||||
;
|
||||
; ]1 : sprite buffer offset
|
||||
; ]2 : code field offset
|
||||
CopyDynWord mac
|
||||
lda tmp_sprite_mask+{]1} ; load the mask value
|
||||
bne mixed ; a non-zero value may be mixed
|
||||
|
||||
; This is a solid word
|
||||
lda #$00F4 ; PEA instruction
|
||||
sta: ]2,y
|
||||
lda tmp_sprite_data+{]1} ; load the sprite data
|
||||
sta: ]2+1,y ; PEA operand
|
||||
bra next
|
||||
|
||||
mixed cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
|
||||
beq transparent
|
||||
|
||||
lda #$004C ; JMP to handler
|
||||
sta: {]2},y
|
||||
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
|
||||
ora #{]2&$F000} ; adjust for the current row offset
|
||||
sta: {]2}+1,y
|
||||
tax ; This becomes the new address that we use to patch in
|
||||
|
||||
lda _OP_CACHE ; Get the LDA dp,x instruction for this column
|
||||
sta: $0000,x
|
||||
|
||||
lda #$0029 ; AND #SPRITE_MASK
|
||||
sta: $0002,x
|
||||
lda tmp_sprite_mask+{]1}
|
||||
sta: $0003,x
|
||||
|
||||
lda #$0009 ; ORA #SPRITE_DATA
|
||||
sta: $0005,x
|
||||
lda tmp_sprite_data+{]1}
|
||||
sta: $0006,x
|
||||
|
||||
lda #$0D80 ; branch to the prologue (BRA *+15)
|
||||
sta: $0008,x
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the dynamic data
|
||||
transparent
|
||||
lda #$4800 ; Put the PHA in the third byte
|
||||
sta: {]2}+1,y
|
||||
lda _OP_CACHE ; Store the LDA dp,x instruction with operand
|
||||
sta: {]2},y
|
||||
next
|
||||
<<<
|
||||
|
||||
; Masked renderer for a dynamic tile with sprite data overlaid.
|
||||
;
|
||||
; ]1 : sprite plane offset
|
||||
; ]2 : code field offset
|
||||
CopyDynSpriteWord MAC
|
||||
|
||||
; Need to fill in the first 10 bytes of the JMP handler with the following code sequence where
|
||||
; the data and mask from from the sprite plane
|
||||
;
|
||||
; lda $00,x
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
; bra *+15
|
||||
;
|
||||
; If MASK == 0, then we can do a PEA. If MASK == $FFFF, then fall back to the simple Dynamic Tile
|
||||
; code.
|
||||
ldal spritemask+{]1},x ; load the mask value
|
||||
bne mixed ; a non-zero value may be mixed
|
||||
|
||||
; This is a solid word
|
||||
lda #$00F4 ; PEA instruction
|
||||
sta: ]2,y
|
||||
ldal spritedata+{]1},x ; load the sprite data
|
||||
sta: ]2+1,y ; PEA operand
|
||||
bra next
|
||||
|
||||
mixed cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
|
||||
beq transparent
|
||||
|
||||
lda #$004C ; JMP to handler
|
||||
sta: ]2,y
|
||||
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
|
||||
ora #{]2&$F000} ; adjust for the current row offset
|
||||
sta: ]2+1,y
|
||||
tay ; This becomes the new address that we use to patch in
|
||||
|
||||
lda _OP_CACHE ; Get the LDA dp,x instruction for this column
|
||||
sta: $0000,y
|
||||
|
||||
lda #$0029 ; AND #SPRITE_MASK
|
||||
sta: $0002,y
|
||||
ldal spritemask+{]1},x
|
||||
sta: $0003,y
|
||||
|
||||
lda #$0009 ; ORA #SPRITE_DATA
|
||||
sta: $0005,y
|
||||
ldal spritedata+{]1},x
|
||||
sta: $0006,y
|
||||
|
||||
lda #$0D80 ; branch to the prologue (BRA *+15)
|
||||
sta: $0008,y
|
||||
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the dynamic data
|
||||
transparent
|
||||
lda #$4800 ; Put the PHA in the third byte
|
||||
sta: ]2+1,y
|
||||
lda _OP_CACHE ; Store the LDA dp,x instruction with operand
|
||||
sta: ]2,y
|
||||
next
|
||||
eom
|
|
@ -1,88 +0,0 @@
|
|||
; _TBMaskedSpriteTile
|
||||
;
|
||||
; Renders a composited tile with masking to the code field.
|
||||
_TBMaskedSpriteTile_00
|
||||
_TBMaskedSpriteTile_0H
|
||||
sta _X_REG ; Immedately stash the parameters
|
||||
sty _Y_REG
|
||||
|
||||
jsr _TBCopyTileDataToCBuff ; Copy the tile data into the compositing buffer (using correct x-register)
|
||||
jsr _TBCopyTileMaskToCBuff ; Copy the tile mask into the compositing buffer (using correct x-register)
|
||||
jsr _TBMergeSpriteDataAndMask ; Overlay the data and mask from the sprite plane into the compositing buffer
|
||||
jmp _TBMaskedCBuff ; Render the masked tile from the compositing buffer into the code field
|
||||
|
||||
;_TBMaskedSpriteTile_0H
|
||||
; sta _X_REG
|
||||
; sty _Y_REG
|
||||
; jsr _TBCopyTileDataToCBuffH
|
||||
; jsr _TBCopyTileMaskToCBuffH
|
||||
; jsr _TBMergeSpriteDataAndMask
|
||||
; jmp _TBMaskedCBuff
|
||||
|
||||
_TBMaskedSpriteTile_V0
|
||||
_TBMaskedSpriteTile_VH
|
||||
sta _X_REG
|
||||
sty _Y_REG
|
||||
jsr _TBCopyTileDataToCBuffV
|
||||
jsr _TBCopyTileMaskToCBuffV
|
||||
jsr _TBMergeSpriteDataAndMask
|
||||
jmp _TBMaskedCBuff
|
||||
|
||||
;_TBMaskedSpriteTile_VH
|
||||
; sta _X_REG
|
||||
; sty _Y_REG
|
||||
; jsr _TBCopyTileDataToCBuffVH
|
||||
; jsr _TBCopyTileMaskToCBuffVH
|
||||
; jsr _TBMergeSpriteDataAndMask
|
||||
; jmp _TBMaskedCBuff
|
||||
|
||||
_TBMergeSpriteDataAndMask
|
||||
ldx _SPR_X_REG ; set to the unaligned tile block address in the sprite plane
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
lda blttmp+{]line*4}
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
sta blttmp+{]line*4}
|
||||
|
||||
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
and blttmp+{]line*4}+32
|
||||
sta blttmp+{]line*4}+32
|
||||
|
||||
lda blttmp+{]line*4}+2
|
||||
andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
sta blttmp+{]line*4}+2
|
||||
|
||||
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
and blttmp+{]line*4}+32+2
|
||||
sta blttmp+{]line*4}+32+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
||||
|
||||
; See the Tiles00010.s blitter for additional details
|
||||
_TBMaskedCBuff
|
||||
CopyMaskedWordD blttmp+0;$0003
|
||||
CopyMaskedWordD blttmp+4;$1003
|
||||
CopyMaskedWordD blttmp+8;$2003
|
||||
CopyMaskedWordD blttmp+12;$3003
|
||||
CopyMaskedWordD blttmp+16;$4003
|
||||
CopyMaskedWordD blttmp+20;$5003
|
||||
CopyMaskedWordD blttmp+24;$6003
|
||||
CopyMaskedWordD blttmp+28;$7003
|
||||
|
||||
inc _X_REG
|
||||
inc _X_REG
|
||||
|
||||
CopyMaskedWordD blttmp+2;$0000
|
||||
CopyMaskedWordD blttmp+6;$1000
|
||||
CopyMaskedWordD blttmp+10;$2000
|
||||
CopyMaskedWordD blttmp+14;$3000
|
||||
CopyMaskedWordD blttmp+18;$4000
|
||||
CopyMaskedWordD blttmp+22;$5000
|
||||
CopyMaskedWordD blttmp+26;$6000
|
||||
CopyMaskedWordD blttmp+30;$7000
|
||||
|
||||
rts
|
|
@ -1,134 +0,0 @@
|
|||
; _TBDynamicMaskedSpriteTile
|
||||
;
|
||||
; This tile type does not explicitly support horizontal or vertical flipping. An appropriate tile
|
||||
; descriptor should be passed into CopyTileToDyn to put the horizontally or vertically flipped source
|
||||
; data into the dynamic tile buffer
|
||||
;
|
||||
; When rendering, the background, via lda (dp),y, is shown behind the animate sprite
|
||||
_TBDynamicMaskedSpriteTile_00
|
||||
sty _Y_REG ; This is restored in the macro
|
||||
|
||||
sta _X_REG ; Cache some column values derived from _X_REG
|
||||
tax
|
||||
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
|
||||
xba
|
||||
sta _OP_CACHE
|
||||
|
||||
clc
|
||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
sta _JTBL_CACHE
|
||||
|
||||
lda _TILE_ID ; Get the original tile descriptor
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
ora #$3580 ; Pre-calc the AND $80,x opcode + operand
|
||||
xba
|
||||
sta _T_PTR ; This is an op to load the dynamic tile data
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynMaskedSpriteWord {0*SPRITE_PLANE_SPAN};$0003
|
||||
CopyDynMaskedSpriteWord {1*SPRITE_PLANE_SPAN};$1003
|
||||
CopyDynMaskedSpriteWord {2*SPRITE_PLANE_SPAN};$2003
|
||||
CopyDynMaskedSpriteWord {3*SPRITE_PLANE_SPAN};$3003
|
||||
CopyDynMaskedSpriteWord {4*SPRITE_PLANE_SPAN};$4003
|
||||
CopyDynMaskedSpriteWord {5*SPRITE_PLANE_SPAN};$5003
|
||||
CopyDynMaskedSpriteWord {6*SPRITE_PLANE_SPAN};$6003
|
||||
CopyDynMaskedSpriteWord {7*SPRITE_PLANE_SPAN};$7003
|
||||
|
||||
ldx _X_REG
|
||||
clc
|
||||
ldal JTableOffset+2,x ; Get the address offset and add to the base address
|
||||
adc _BASE_ADDR ; of the current code field line
|
||||
sta _JTBL_CACHE
|
||||
|
||||
lda _OP_CACHE
|
||||
adc #$0200
|
||||
sta _OP_CACHE
|
||||
lda _T_PTR
|
||||
adc #$0200
|
||||
sta _T_PTR
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynMaskedSpriteWord {0*SPRITE_PLANE_SPAN}+2;$0000
|
||||
CopyDynMaskedSpriteWord {1*SPRITE_PLANE_SPAN}+2;$1000
|
||||
CopyDynMaskedSpriteWord {2*SPRITE_PLANE_SPAN}+2;$2000
|
||||
CopyDynMaskedSpriteWord {3*SPRITE_PLANE_SPAN}+2;$3000
|
||||
CopyDynMaskedSpriteWord {4*SPRITE_PLANE_SPAN}+2;$4000
|
||||
CopyDynMaskedSpriteWord {5*SPRITE_PLANE_SPAN}+2;$5000
|
||||
CopyDynMaskedSpriteWord {6*SPRITE_PLANE_SPAN}+2;$6000
|
||||
CopyDynMaskedSpriteWord {7*SPRITE_PLANE_SPAN}+2;$7000
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; Masked renderer for a masked dynamic tile with sprite data overlaid.
|
||||
;
|
||||
; ]1 : sprite plane offset
|
||||
; ]2 : code field offset
|
||||
CopyDynMaskedSpriteWord MAC
|
||||
|
||||
; Need to fill in the first 14 bytes of the JMP handler with the following code sequence where
|
||||
; the data and mask from from the sprite plane
|
||||
;
|
||||
; lda ($00),y
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
; bra *+15
|
||||
;
|
||||
; If MASK == 0, then we can do a PEA. If MASK == $FFFF, then fall back to the simple Dynamic Tile
|
||||
; code and eliminate the constanct AND/ORA instructions.
|
||||
|
||||
ldal spritemask+{]1},x ; load the mask value
|
||||
bne mixed ; a non-zero value may be mixed
|
||||
|
||||
; This is a solid word
|
||||
lda #$00F4 ; PEA instruction
|
||||
sta: ]2,y
|
||||
ldal spritedata+{]1},x ; load the sprite data
|
||||
sta: ]2+1,y ; PEA operand
|
||||
bra next
|
||||
|
||||
; We will always do a JMP to the eception handler, so set that up, then check for sprite
|
||||
; transparency
|
||||
mixed
|
||||
lda #$004C ; JMP to handler
|
||||
sta: ]2,y
|
||||
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
|
||||
ora #{]2&$F000} ; adjust for the current row offset
|
||||
sta: {]2}+1,y
|
||||
tay ; This becomes the new address that we use to patch in
|
||||
|
||||
lda _OP_CACHE
|
||||
sta: $0000,y ; LDA (00),y
|
||||
lda _T_PTR
|
||||
sta: $0002,y ; AND $80,x
|
||||
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||
sta: $0004,y ; ORA $00,x
|
||||
|
||||
lda #$0029 ; AND #SPRITE_MASK
|
||||
sta: $0006,y
|
||||
ldal spritemask+{]1},x
|
||||
cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
|
||||
beq transparent ; so we can use the Tile00011 method
|
||||
sta: $0007,y
|
||||
|
||||
lda #$0009 ; ORA #SPRITE_DATA
|
||||
sta: $0009,y
|
||||
ldal spritedata+{]1},x
|
||||
sta: $000A,y
|
||||
|
||||
lda #$0980 ; branch to the prologue (BRA *+11)
|
||||
sta: $000C,y
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the dynamic data
|
||||
transparent
|
||||
lda #$0F80 ; branch to the epilogue (BRA *+17)
|
||||
sta: $0006,y
|
||||
next
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
eom
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue