-
-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #293 from nub1604/develop
feat(*) mapbuffer example + extension
- Loading branch information
Showing
13 changed files
with
2,606 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
ifeq ($(strip $(PVSNESLIB_HOME)),) | ||
$(error "Please create an environment variable PVSNESLIB_HOME by following this guide: https://github.com/alekmaul/pvsneslib/wiki/Installation") | ||
endif | ||
|
||
include ${PVSNESLIB_HOME}/devkitsnes/snes_rules | ||
|
||
.PHONY: bitmaps all | ||
|
||
MAPDIR := ./maps/$(MAPDIR) | ||
GFXDIR := ./gfx/$(GFXDIR) | ||
|
||
CFLAGS += -I$(CURDIR)/maps $\ | ||
-I$(CURDIR)/src/gameobjects $\ | ||
-I$(CURDIR)/src/addons $\ | ||
|
||
#--------------------------------------------------------------------------------- | ||
# ROMNAME is used in snes_rules file | ||
export ROMNAME := mapbuffer | ||
|
||
all: bitmaps $(ROMNAME).sfc | ||
|
||
clean: cleanBuildRes cleanRom cleanGfx | ||
@rm -f $(GFXDIR)*.map $(GFXDIR)*.pal $(GFXDIR)*.pic | ||
@rm -f $(MAPDIR)*.m16 $(MAPDIR)*.t16 $(MAPDIR)*.o16 $(MAPDIR)*.b16 $(MAPDIR)*.r16 | ||
|
||
#--------------------------------------------------------------------------------- | ||
tilesMario.pic: $(GFXDIR)tilesMario.png | ||
@echo convert font with no tile reduction ... $(notdir $@) | ||
$(GFXCONV) -s 8 -o 48 -u 16 -p -m -i $< | ||
|
||
BG1.m16: $(MAPDIR)tiledMario.tmj tilesMario.pic | ||
@echo convert map tiled ... $(notdir $@) | ||
$(TMXCONV) $< $(MAPDIR)tilesMario.map | ||
|
||
mario.pic: $(GFXDIR)mario.png | ||
@echo convert sprite bitmap ... $(notdir $@) | ||
$(GFXCONV) -s 16 -o 16 -u 16 -p -i $< | ||
|
||
bitmaps : mario.pic tilesMario.pic BG1.m16 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
.include "hdr.asm" | ||
|
||
.section ".rodata1" superfree | ||
|
||
tileset: | ||
.incbin "gfx/tilesMario.pic" | ||
tilesetend: | ||
|
||
tilesetpal: | ||
.incbin "gfx/tilesMario.pal" | ||
|
||
|
||
mapmario: | ||
.incbin "maps/BG1.m16" | ||
mapmario_end: | ||
|
||
tilesetatt: | ||
.incbin "maps/tiledMario.b16" | ||
|
||
tilesetdef: | ||
.incbin "maps/tiledMario.t16" | ||
|
||
objmario: | ||
.incbin "maps/tiledMario.o16" | ||
|
||
.ends | ||
|
||
.section ".rodata2" superfree | ||
|
||
gfxsprite: | ||
.incbin "gfx/mario.pic" | ||
gfxsprite_end: | ||
|
||
palsprite: | ||
.incbin "gfx/mario.pal" | ||
|
||
.ends |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
;==LoRom== ; We'll get to HiRom some other time. | ||
|
||
.MEMORYMAP ; Begin describing the system architecture. | ||
SLOTSIZE $8000 ; The slot is $8000 bytes in size. More details on slots later. | ||
DEFAULTSLOT 0 ; There's only 1 slot in SNES, there are more in other consoles. | ||
SLOT 0 $8000 ; Defines Slot 0's starting address. | ||
SLOT 1 $0 $2000 | ||
SLOT 2 $2000 $E000 | ||
SLOT 3 $0 $10000 | ||
.ENDME ; End MemoryMap definition | ||
|
||
.ROMBANKSIZE $8000 ; Every ROM bank is 32 KBytes in size | ||
.ROMBANKS 8 ; 2 Mbits - Tell WLA we want to use 8 ROM Banks | ||
|
||
.SNESHEADER | ||
ID "SNES" ; 1-4 letter string, just leave it as "SNES" | ||
|
||
NAME "LIBSNES TIMER SAMPLE " ; Program Title - can't be over 21 bytes, | ||
; "123456789012345678901" ; use spaces for unused bytes of the name. | ||
|
||
SLOWROM | ||
LOROM | ||
|
||
CARTRIDGETYPE $00 ; $00 = ROM only $02 = ROM+SRAM, see WLA documentation for others | ||
ROMSIZE $08 ; $08 = 2 Mbits, see WLA doc for more.. | ||
SRAMSIZE $00 ; $00 = No Sram, $01 = 16 kbits, see WLA doc for more.. | ||
COUNTRY $01 ; $01 = U.S. $00 = Japan, that's all I know | ||
LICENSEECODE $00 ; Just use $00 | ||
VERSION $00 ; $00 = 1.00, $01 = 1.01, etc. | ||
.ENDSNES | ||
|
||
.SNESNATIVEVECTOR ; Define Native Mode interrupt vector table | ||
COP EmptyHandler | ||
BRK EmptyHandler | ||
ABORT EmptyHandler | ||
NMI VBlank | ||
IRQ EmptyHandler | ||
.ENDNATIVEVECTOR | ||
|
||
.SNESEMUVECTOR ; Define Emulation Mode interrupt vector table | ||
COP EmptyHandler | ||
ABORT EmptyHandler | ||
NMI EmptyHandler | ||
RESET tcc__start ; where execution starts | ||
IRQBRK EmptyHandler | ||
.ENDEMUVECTOR |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/*--------------------------------------------------------------------------------- | ||
Simple map example with object scrolling | ||
-- alekmaul | ||
---------------------------------------------------------------------------------*/ | ||
#include <snes.h> | ||
|
||
#include "mario.h" | ||
#include "mapbufferextension.h" | ||
|
||
extern char objmario; | ||
extern char tileset, tilesetend, tilesetpal; // for map & tileset of map | ||
|
||
extern char mapmario, mapmario_end, tilesetdef, tilesetatt; | ||
|
||
extern u16 mapwidth; | ||
|
||
//--------------------------------------------------------------------------------- | ||
unsigned short pad0; | ||
|
||
//--------------------------------------------------------------------------------- | ||
int main(void) | ||
{ | ||
|
||
bgInitTileSet(0, &tileset, &tilesetpal, 0, (&tilesetend - &tileset), 16 * 2, BG_16COLORS, 0x2000); | ||
bgSetMapPtr(0, 0x6800, SC_64x32); | ||
|
||
// Now Put in 16 color mode and disable Bgs except current | ||
setMode(BG_MODE1, 0); | ||
bgSetDisable(1); | ||
bgSetDisable(2); | ||
|
||
// Init Sprites gfx and palette with default size of 16x16 | ||
oamInitDynamicSprite(0x0000, 0x1000, 0, 0, OBJ_SIZE8_L16); | ||
// Object engine activate | ||
objInitEngine(); | ||
// Init function for state machine | ||
objInitFunctions(0, &marioinit, &marioupdate, NULL); | ||
|
||
// Load all objects into memory | ||
objLoadObjects((char *)&objmario); | ||
|
||
// load map into wram | ||
mapbuffersLoad((u8 *)&mapmario, (&mapmario_end - &mapmario)); | ||
// map engine gets the buffer instead | ||
mapLoad((u8 *)&mapbuffer, (u8 *)&tilesetdef, (u8 *)&tilesetatt); | ||
// | ||
dynamicTileBuffer_Init(); | ||
|
||
setScreenOn(); | ||
WaitForVBlank(); | ||
while (1) | ||
{ | ||
// Update all the available objects | ||
objUpdateAll(); | ||
|
||
// prepare next frame and wait vblank | ||
mapUpdate(); | ||
DynamicTileAutoUpdate(); | ||
maptileQueueUpdate(); | ||
oamInitDynamicSpriteEndFrame(); | ||
WaitForVBlank(); | ||
mapVblank(); | ||
maptileVRAMUpdate(); | ||
oamVramQueueUpdate(); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
## MapBuffer Extension | ||
|
||
### Desciption: | ||
|
||
- this addon extends the ability of PVSneslibs mapengine to change tiles during runtime. | ||
|
||
|
||
### Installation: | ||
|
||
- copy the following files to your source folder | ||
> "mapbufferextension.h","mapbufferextension.c", "mapbufferextensionA.asm" | ||
- include with mapbufferextension.h to your c files, where you need the extension | ||
> #include "mapbufferrextension.h" | ||
### Load maps into mapbuffer[] | ||
|
||
- first load the map into the buffer with the mapbuffersLoad | ||
- than call mapLoad as usual but now we point to the mapbuffer | ||
```c | ||
#include "mapbufferextension.h" | ||
... | ||
//load map into wram | ||
mapbuffersLoad((u8 *)&mapmario, (&mapmario_end- &mapmario)); | ||
//map engine gets the buffer instead | ||
mapLoad((u8 *)&mapbuffer, (u8 *)&tilesetdef, (u8 *)&tilesetatt); | ||
``` | ||
congrats the easy part is done, now you can manipulate the map during runtime. | ||
when you manipulate the maptiles in ram it doesn't mean the vram ram will be updated. | ||
there are two ways to solve this problem | ||
### Update vram 1 slow | ||
one way to update the onscreen tiles is to set "mapdirty" to 1 | ||
```c | ||
mapbuffer[123] = 0x0001; | ||
mapdirty = 1; | ||
``` | ||
- this updates the entire screen to the vram | ||
- if frames doesn't matter, this the way to go | ||
|
||
### Update vram 2 fast | ||
|
||
the second approach uses additional buffers, the sequence is the following: | ||
|
||
1. select and check a tile | ||
2. prebuffer the tile | ||
3. manipulate the tile | ||
4. push tiles that are currently on screen to a queue before v-blank | ||
5. update vram from queue during v-blank | ||
|
||
##### Detailed steps: | ||
|
||
1. the first function __mapGetMetaTilesInfo__ is similar to __mapGetMetaTilesProp__ but it prestores some variables which are preparation for __dynamictilebuffer__ -> __dtb__. | ||
|
||
2. the next function __GetDynamicTileID__ returns will setup or update the __dtb__ and it returns the index which can be used by on of the next function. | ||
|
||
3. Manipulating variants | ||
|
||
1. the __mapChangeTileByID__ takes the index of the __dtb__, the new tile number and the tile attributes (tile attributes not fully integrated) | ||
|
||
2. __ManipulateDynamicTile__ extends the __mapChangeTileByID__, this is an example | ||
of event driven tile manipulation (hit by head, stand on it.) feel free to extend it or write you own logic | ||
|
||
3. __DynamicTileAutoUpdate__ extends the __mapChangeTileByID__, this is an example how to manipulate a tile over time, feel free to extend it or write you own logic call it once before __maptileQueueUpdate__ | ||
|
||
4. __maptileQueueUpdate__ pushes tiles from __dtb__ into a __dynamictilequeue__ (__dtq__) when there on screen, call it once before WaitForVBlank | ||
|
||
|
||
5. the __maptileVRAMUpdate__ function update all queued tiles in the __dtq__ into vram __queuetilebuffer__ and flush the queue, call it once after WaitForVBlank because vram access is only allowed during v-blank | ||
|
||
### Important notes and limitations | ||
|
||
|
||
|
||
- **!!!** only map widths based on __power of two__ are allowed | ||
> tested map widths: 32, 62, 128 | ||
- **!!!** only testet with lowrom, the bank for wram is set to__$7F__ by default. | ||
```assembly | ||
;mapbufferextensionA.asm: | ||
.DEFINE DTBUFFERBANK $7F | ||
``` | ||
- manipulated offscreen tiles will be updated by mapUpdateCamera when the scree is scrolling | ||
|
||
- the map size in byte must not exceed the size of the mapbuffer | ||
> default 16.387 bytes (4003 hex), 3 bytes for the header, it is defined in asm file | ||
```assembly | ||
;mapbufferextensionA.asm: | ||
.DEFINE MAPBUFFER_SIZE $4003 | ||
``` | ||
> the calculation of the map in bytes: (3+ 2*(mapheightblock * block width)) | ||
- the size of __dtb__ and the __dtq__ is set to 32 by default | ||
- to change the size of __dynamictilebuffer__ has to be set in the header and the asm file as well | ||
|
||
|
||
```assembly | ||
;mapbufferextensionA.asm: | ||
.DEFINE DTBUFFER_MAX 32 | ||
.DEFINE DTQUEUE_MAX 32 | ||
``` | ||
|
||
```c | ||
//mapbufferextension.h: | ||
#define DTBUFFER_MAX 32 // same value like in the asm file! | ||
``` | ||
- to change the size of __dynamictilequeue__ has to be set asm file |
Oops, something went wrong.