├── .gitignore ├── LICENSE ├── Makefile ├── adv ├── Makefile ├── m7_demo │ ├── Makefile │ ├── graphics │ │ ├── nums.grit │ │ └── nums.png │ └── source │ │ ├── m7_demo.c │ │ ├── m7_demo.h │ │ └── m7_isrs.iwram.c ├── m7_ex │ ├── Makefile │ ├── graphics │ │ ├── bc1floor.grit │ │ ├── bc1floor.png │ │ ├── bc1sky.grit │ │ ├── bc1sky.png │ │ ├── bgpal.grit │ │ ├── bgpal.png │ │ ├── border.grit │ │ ├── border.png │ │ ├── karts.grit │ │ ├── karts.png │ │ ├── objpal.grit │ │ ├── objpal.png │ │ ├── thwomp.grit │ │ └── thwomp.png │ └── source │ │ ├── id_sort_shell.s │ │ ├── m7_ex.c │ │ ├── mode7.c │ │ ├── mode7.h │ │ └── mode7.iwram.c ├── tte_demo │ ├── Makefile │ ├── fonts │ │ ├── cyber16.h │ │ ├── cyber16.png │ │ ├── cyber16.s │ │ ├── fonts.h │ │ ├── mssans9.h │ │ ├── mssans9.png │ │ ├── mssans9.s │ │ ├── tahoma9.h │ │ ├── tahoma9.png │ │ ├── tahoma9.s │ │ ├── verdana11.h │ │ ├── verdana11.png │ │ ├── verdana11.s │ │ ├── yesh1.h │ │ ├── yesh1.png │ │ └── yesh1.s │ ├── graphics │ │ ├── dlgbox.grit │ │ ├── dlgbox.png │ │ ├── dungeon01.grit │ │ ├── dungeon01.png │ │ ├── menu_gfx.grit │ │ └── menu_gfx.png │ ├── include │ │ └── menu.h │ ├── readme.md │ └── source │ │ ├── main.c │ │ ├── menu.c │ │ ├── slideshow.c │ │ └── tte_profile.c ├── txt_bm │ ├── Makefile │ └── source │ │ └── txt_bm.c ├── txt_obj │ ├── Makefile │ └── source │ │ └── txt_obj.c ├── txt_se1 │ ├── Makefile │ ├── border-original.png │ ├── graphics │ │ ├── border.grit │ │ └── border.png │ └── source │ │ └── txt_se1.c └── txt_se2 │ ├── Makefile │ ├── graphics │ ├── gba_pic.grit │ └── gba_pic.png │ └── source │ └── txt_se2.c ├── basic ├── Makefile ├── bm_modes │ ├── Makefile │ ├── graphics │ │ ├── modes.grit │ │ ├── modes.png │ │ ├── modes_pal.grit │ │ └── modes_pal.png │ └── source │ │ └── bm_modes.c ├── brin_demo │ ├── Makefile │ ├── graphics │ │ ├── brin.grit │ │ └── brin.png │ └── source │ │ └── brin_demo.c ├── cbb_demo │ ├── Makefile │ ├── cbb_ids.png │ └── source │ │ ├── cbb_demo.c │ │ ├── cbb_ids.c │ │ └── cbb_ids.h ├── first │ ├── Makefile │ └── source │ │ └── first.c ├── hello │ ├── Makefile │ └── source │ │ └── hello.c ├── key_demo │ ├── Makefile │ ├── graphics │ │ ├── gba_pic.grit │ │ └── gba_pic.png │ └── source │ │ └── key_demo.c ├── m3_demo │ ├── Makefile │ └── source │ │ └── m3_demo.c ├── obj_demo │ ├── Makefile │ ├── graphics │ │ ├── metr.grit │ │ └── metr.png │ └── source │ │ └── obj_demo.c ├── pageflip │ ├── Makefile │ ├── graphics │ │ ├── page_pic.grit │ │ └── page_pic.png │ └── source │ │ └── pageflip.c ├── sbb_reg │ ├── Makefile │ └── source │ │ └── sbb_reg.c └── second │ ├── Makefile │ └── source │ └── second.c ├── ext ├── Makefile ├── bld_demo │ ├── Makefile │ ├── graphics │ │ ├── metr.grit │ │ └── metr.png │ └── source │ │ └── bld_demo.c ├── dma_demo │ ├── Makefile │ ├── graphics │ │ ├── brin.grit │ │ └── brin.png │ └── source │ │ └── dma_demo.c ├── irq_demo │ ├── Makefile │ └── source │ │ ├── irq_demo.c │ │ └── isr.iwram.c ├── mos_demo │ ├── Makefile │ ├── graphics │ │ ├── metr.grit │ │ └── metr.png │ └── source │ │ └── mos_demo.c ├── oacombo │ ├── Makefile │ ├── graphics │ │ ├── oac_gfx.grit │ │ └── oac_gfx.png │ └── source │ │ ├── oacombo.c │ │ └── oe_rs_ex.s ├── obj_aff │ ├── Makefile │ ├── graphics │ │ ├── metr.grit │ │ └── metr.png │ └── source │ │ └── obj_aff.c ├── sbb_aff │ ├── Makefile │ ├── graphics │ │ ├── nums.grit │ │ └── nums.png │ └── source │ │ └── sbb_aff.c ├── snd1_demo │ ├── Makefile │ └── source │ │ └── snd1_demo.c ├── swi_demo │ ├── Makefile │ └── source │ │ └── swi_demo.c ├── swi_vsync │ ├── Makefile │ ├── graphics │ │ ├── metr.grit │ │ └── metr.png │ └── source │ │ └── swi_vsync.c ├── tmr_demo │ ├── Makefile │ ├── berk.bmp │ ├── berk.txt │ ├── graphics │ │ ├── berk.grit │ │ └── berk.png │ └── source │ │ └── tmr_demo.c └── win_demo │ ├── Makefile │ ├── graphics │ ├── nums.grit │ ├── nums.png │ ├── rocket.grit │ └── rocket.png │ └── source │ └── win_demo.c ├── lab ├── Makefile ├── bigmap │ ├── Makefile │ ├── graphics │ │ ├── kakariko.grit │ │ ├── kakariko.png │ │ ├── link_gfx.grit │ │ └── link_gfx.png │ └── source │ │ ├── bigmap.c │ │ ├── link.c │ │ └── link.h ├── octtest │ ├── Makefile │ ├── graphics │ │ ├── octants.grit │ │ └── octants.png │ ├── source │ │ └── octtest.c │ └── turret.png ├── prio_demo │ ├── Makefile │ ├── graphics │ │ ├── ball.grit │ │ ├── ball.png │ │ ├── cage.grit │ │ └── cage.png │ └── source │ │ ├── id_sort_shell2.s │ │ ├── prio.iwram.c │ │ └── prio_demo.c └── template │ ├── Makefile │ └── source │ └── main.c ├── readme.md └── tonc-code.txt /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | build/ 3 | *.sav 4 | *.gba 5 | *.elf 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS:= `ls` 2 | 3 | #--------------------------------------------------------------------------------- 4 | all: examples 5 | #--------------------------------------------------------------------------------- 6 | @rm -fr bin 7 | @mkdir -p bin 8 | @find . -path ./bin -prune -o -name "*.gba" -exec cp -fv {} bin \; 9 | 10 | examples: 11 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i || { exit 1;} fi; done; 12 | 13 | #--------------------------------------------------------------------------------- 14 | clean: 15 | #--------------------------------------------------------------------------------- 16 | @rm -fr bin 17 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i clean || { exit 1;} fi; done; 18 | -------------------------------------------------------------------------------- /adv/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS:= `ls` 2 | 3 | all: 4 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i || { exit 1;} fi; done; 5 | clean: 6 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i clean || { exit 1;} fi; done; 7 | -------------------------------------------------------------------------------- /adv/m7_demo/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /adv/m7_demo/graphics/nums.grit: -------------------------------------------------------------------------------- 1 | # 2 | # nums.png : 8bpp tiles, with palette 3 | # 4 | 5 | -gt -gB8 -pn 32 -------------------------------------------------------------------------------- /adv/m7_demo/graphics/nums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_demo/graphics/nums.png -------------------------------------------------------------------------------- /adv/m7_demo/source/m7_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // m7_demo.c 3 | // block, sawtooth and smooth mode7 in one demo :) 4 | // Using pre-calculated LUTs, courtesy of my excellut program 5 | // 6 | // 7 | // Coordinate system: 8 | // 9 | // y 10 | // | 11 | // |___x 12 | // z / 13 | // 14 | // The viewing direction is in the NEGATIVE z direction!! 15 | // 16 | // (20040104 - 20070808, Cearn) 17 | 18 | #include 19 | #include 20 | 21 | #include "m7_demo.h" 22 | #include "nums.h" 23 | 24 | // === CONSTANTS & MACROS ============================================= 25 | 26 | #define MAP_AFF_SIZE 0x0100 27 | #define PHI0 0 28 | 29 | static const VECTOR cam_pos_default= { 256<<8, 32<<8, 256<<8 }; 30 | 31 | CSTR strings[]= 32 | { 33 | "A: blocky", 34 | "B: sawtooth", 35 | "C: smooth" 36 | }; 37 | 38 | // === GLOBALS ======================================================== 39 | 40 | VECTOR cam_pos; 41 | u16 cam_phi= PHI0; 42 | 43 | FIXED g_cosf= 1<<8, g_sinf= 0; // temporaries for cos and sin cam_phi 44 | int g_state= M7_BLOCK; 45 | 46 | 47 | fnptr m7_isrs[3]= 48 | { 49 | (fnptr)m7_hbl_a, 50 | (fnptr)m7_hbl_b, 51 | (fnptr)m7_hbl_c, 52 | }; 53 | 54 | // === FUNCTIONS ====================================================== 55 | 56 | void init_main() 57 | { 58 | int ii; 59 | 60 | cam_pos= cam_pos_default; 61 | 62 | GRIT_CPY(&tile8_mem[0][1], numsTiles); 63 | GRIT_CPY(pal_bg_mem, numsPal); 64 | 65 | // Fill the map with a band pattern 66 | for(ii=0; ii<16; ii++) 67 | memset32(&se_mem[8][ii*16*16/2], quad8(ii+1), 16*16/4); 68 | 69 | REG_BG2CNT= BG_CBB(0) | BG_SBB(8) | BG_AFF_64x64; 70 | } 71 | 72 | void input_main() 73 | { 74 | const FIXED speed= 2, DY= 64; 75 | VECTOR dir; 76 | 77 | key_poll(); 78 | 79 | dir.x= speed*key_tri_horz(); // left/right : strafe 80 | dir.y= DY* key_tri_fire(); // B/A : rise/sink 81 | dir.z= speed*key_tri_vert(); // up/down : forward/back 82 | 83 | cam_pos.x += dir.x*g_cosf - dir.z*g_sinf; 84 | cam_pos.y += dir.y; 85 | cam_pos.z += dir.x*g_sinf + dir.z*g_cosf; 86 | 87 | if(cam_pos.y<0) 88 | cam_pos.y= 0; 89 | 90 | cam_phi += 128*key_tri_shoulder(); 91 | 92 | if(key_hit(KEY_START)) 93 | { 94 | cam_pos= cam_pos_default; 95 | cam_phi= PHI0; 96 | set_mode7_type(M7_BLOCK); 97 | } 98 | 99 | if(key_hit(KEY_SELECT)) 100 | set_mode7_type(g_state+1); 101 | 102 | g_cosf= lu_cos(cam_phi)>>4; 103 | g_sinf= lu_sin(cam_phi)>>4; 104 | } 105 | 106 | int main() 107 | { 108 | init_main(); 109 | 110 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 111 | tte_init_con(); 112 | tte_set_margins(8, 8, 232, 40); 113 | 114 | // enable hblank register and set the mode7 type 115 | irq_init(NULL); 116 | irq_add(II_HBLANK, NULL); 117 | // and vblank int for vsync 118 | irq_add(II_VBLANK, NULL); 119 | set_mode7_type(M7_BLOCK); 120 | 121 | REG_DISPCNT= DCNT_MODE1 | DCNT_BG0 | DCNT_BG2; 122 | 123 | // main loop 124 | while(1) 125 | { 126 | VBlankIntrWait(); 127 | input_main(); 128 | } 129 | return 0; 130 | } 131 | 132 | // === MODE7 TYPES ==================================================== 133 | 134 | void set_mode7_type(int type) 135 | { 136 | type= wrap(type, M7_BLOCK, M7_SMOOTH+1); 137 | 138 | irq_add(II_HBLANK, m7_isrs[type]); 139 | 140 | g_state= type; 141 | 142 | tte_printf("#{es;P}%s", strings[g_state]); 143 | } 144 | -------------------------------------------------------------------------------- /adv/m7_demo/source/m7_demo.h: -------------------------------------------------------------------------------- 1 | // 2 | // m7_isrs.c 3 | // Separate file for HBL interrupts because apparently it screws up 4 | // on hardware now. 5 | 6 | #include 7 | 8 | #ifndef __M7_DEMO__ 9 | #define __M7_DEMO__ 10 | 11 | // === CONSTANTS & MACROS ============================================= 12 | 13 | #define M7_D 160 14 | 15 | enum eMode7Type 16 | { M7_BLOCK=0, M7_SAW, M7_SMOOTH}; 17 | 18 | 19 | // === GLOBALS ======================================================== 20 | 21 | extern VECTOR cam_pos; 22 | extern u16 cam_phi; 23 | extern FIXED g_cosf, g_sinf; 24 | extern int g_state; 25 | 26 | // === PROTOTYPES ===================================================== 27 | 28 | void set_mode7_type(int type); 29 | 30 | IWRAM_CODE void m7_hbl_a(); 31 | IWRAM_CODE void m7_hbl_b(); 32 | IWRAM_CODE void m7_hbl_c(); 33 | 34 | #endif // __M7_DEMO__ 35 | -------------------------------------------------------------------------------- /adv/m7_demo/source/m7_isrs.iwram.c: -------------------------------------------------------------------------------- 1 | // 2 | // m7_isrs.iwram.c 3 | // Separate file for HBL interrupts because apparently it screws up 4 | // on hardware now. 5 | 6 | #include 7 | 8 | #include "m7_demo.h" 9 | 10 | 11 | // Perspective zoom for this scanline 12 | // Note that this is actually wrong, because 13 | // the hblank occurs AFTER REG_VCOUNT is drawn, screwing up 14 | // at scanline 0. Oh well. 15 | 16 | /////////////////////////////////////////////////////////////////////// 17 | 18 | // --- Type A --- 19 | // By the numbers: everything nice and .8 fixed point. Result: blocky 20 | // - (offset * zoom) * rotate 21 | // - lambda is .8f for xs and ys 22 | // - M7_D multiplied before shift 23 | void m7_hbl_a() 24 | { 25 | FIXED lam, xs, ys; 26 | 27 | lam= cam_pos.y*lu_div(REG_VCOUNT)>>16; // .8*.16/.16 = .8 28 | 29 | // Calculate offsets (.8) 30 | xs= 120*lam; 31 | ys= M7_D*lam; 32 | 33 | REG_BG2PA= (g_cosf*lam)>>8; 34 | REG_BG2PC= (g_sinf*lam)>>8; 35 | 36 | REG_BG2X = cam_pos.x - ( (xs*g_cosf-ys*g_sinf)>>8 ); 37 | REG_BG2Y = cam_pos.z - ( (xs*g_sinf+ys*g_cosf)>>8 ); 38 | } 39 | 40 | 41 | // --- Type B --- 42 | // Partially correct, but with jaggies 43 | // - (offset * zoom) * rotate 44 | // - lambda is .12f for xs and ys 45 | // - 120 multiplied before shift in xs 46 | // * .16 lambda wouldn't work due to 47 | void m7_hbl_b() 48 | { 49 | FIXED lam, xs, ys; 50 | 51 | lam= cam_pos.y*lu_div(REG_VCOUNT)>>12; // .8*.16/.8 = .12 52 | 53 | // Calculate offsets (.12f) 54 | xs= 120*lam; 55 | ys= M7_D*lam; 56 | 57 | REG_BG2PA= (g_cosf*lam)>>12; 58 | REG_BG2PC= (g_sinf*lam)>>12; 59 | 60 | REG_BG2X = cam_pos.x - ( (xs*g_cosf-ys*g_sinf)>>12 ); 61 | REG_BG2Y = cam_pos.z - ( (xs*g_sinf+ys*g_cosf)>>12 ); 62 | } 63 | 64 | // --- Type C --- 65 | //'proper' mode 7, with mixed fixed-point. Smooth 66 | // - offset * (zoom * rotate) 67 | // - lambda is .12f for xs and ys 68 | // - 120 multiplied before shift in xs 69 | // * .12 lambda,lcf,lsf would work too. 70 | void m7_hbl_c() 71 | { 72 | FIXED lam, lcf, lsf, lxr, lyr; 73 | 74 | lam= cam_pos.y*lu_div(REG_VCOUNT)>>12; // .8*.16 /.12 = 20.12 75 | lcf= lam*g_cosf>>8; // .12*.8 /.8 = .12 76 | lsf= lam*g_sinf>>8; // .12*.8 /.8 = .12 77 | 78 | REG_BG2PA= lcf>>4; 79 | REG_BG2PC= lsf>>4; 80 | 81 | // Offsets 82 | // Note that the lxr shifts down first! 83 | 84 | // horizontal offset 85 | lxr= 120*(lcf>>4); lyr= (M7_D*lsf)>>4; 86 | REG_BG2X= cam_pos.x - lxr + lyr; 87 | 88 | // vertical offset 89 | lxr= 120*(lsf>>4); lyr= (M7_D*lcf)>>4; 90 | REG_BG2Y= cam_pos.z - lxr - lyr; 91 | } 92 | -------------------------------------------------------------------------------- /adv/m7_ex/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /adv/m7_ex/graphics/bc1floor.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Bowser's Castle I floor : affine map, 128x128t, LZ77 compressed. 3 | # 4 | -gB8 -mRa -mLa -p! -Zl -------------------------------------------------------------------------------- /adv/m7_ex/graphics/bc1floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/bc1floor.png -------------------------------------------------------------------------------- /adv/m7_ex/graphics/bc1sky.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Bowser's Castle I sky : normal map, 64x32t, LZ77 compressed. 3 | # 4 | -gB4 -mLs -mR4 -ma 128 -p! -Zl -------------------------------------------------------------------------------- /adv/m7_ex/graphics/bc1sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/bc1sky.png -------------------------------------------------------------------------------- /adv/m7_ex/graphics/bgpal.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Background palette, LZ77 compressed. 3 | # 4 | -gB8 -g! -s bg -Zl -------------------------------------------------------------------------------- /adv/m7_ex/graphics/bgpal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/bgpal.png -------------------------------------------------------------------------------- /adv/m7_ex/graphics/border.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Menu borders, LZ77 compressed. 3 | # 4 | -gt -gB4 -gzl -------------------------------------------------------------------------------- /adv/m7_ex/graphics/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/border.png -------------------------------------------------------------------------------- /adv/m7_ex/graphics/karts.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Karts. Not compressed. 3 | # 4 | -gt -gB4 -Mw4 -Mh4 -p! -------------------------------------------------------------------------------- /adv/m7_ex/graphics/karts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/karts.png -------------------------------------------------------------------------------- /adv/m7_ex/graphics/objpal.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Object palette, LZ77 compressed. 3 | # 4 | -gB8 -g! -s obj -Zl 5 | -------------------------------------------------------------------------------- /adv/m7_ex/graphics/objpal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/objpal.png -------------------------------------------------------------------------------- /adv/m7_ex/graphics/thwomp.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Thwomp tiles, LZ77 compressed. 3 | # 4 | -gt -gB4 -p! -Zl -------------------------------------------------------------------------------- /adv/m7_ex/graphics/thwomp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/graphics/thwomp.png -------------------------------------------------------------------------------- /adv/m7_ex/source/id_sort_shell.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ id_sort_shell2: general shellsort unsing an index table 3 | @ MAXCOUNT: 256 4 | @ === NOTES: === 5 | @ * changed from oe->fill keys to int keys after completion; 6 | @ not fully optimised for that yet. 7 | 8 | .section .iwram,"ax",%progbits 9 | .align 2 10 | @ DECL: CODE_IN_IWRAM void id_sort_shell(int keys[], u8 ids[], int count) 11 | @ r0: sort key (oe.fill) 12 | @ r1: sort indices 13 | @ r2: array length 14 | @ r3: inc 15 | @ r4, r5, r6: inc, ii, jj, jj-inc 16 | @ r7: id= ids[jj-inc] 17 | @ r8, r9: id0=ids[ii], key0=fill[ids[ii]] 18 | @ r10: fill[id] 19 | @ r12: (1<<32)/3 20 | .global id_sort_shell 21 | id_sort_shell: 22 | stmfd sp!, {r4-r10} 23 | @ TODO: special for count==1 24 | @ setup inc: inc= 3*inc+1 25 | mov r3, #0 26 | .Lshell_inc_setup: 27 | rsb r3, r3, r3, lsl #2 28 | add r3, r3, #1 29 | cmp r3, r2 30 | ble .Lshell_inc_setup 31 | ldr r12, .Lshell_pool 32 | @ inc loop 33 | .Lshell_inc_loop: 34 | umull r5, r4, r12, r3 @ ii= inc/3 35 | mov r3, r4 @ inc= ii 36 | cmp r3, r2 @ ii>count 37 | bgt .Lshell_up_loop_end 38 | @ ii=inc to nn loop 39 | .Lshell_up_loop: 40 | ldrb r8, [r1, r4] @ id0= ids[ii] 41 | ldr r9, [r0, r8, lsl #2] @ key0= fill[ids[ii]] 42 | mov r5, r4 @ jj= ii 43 | sub r6, r5, r3 @ jnext= jj-inc 44 | @ jj=ii to 0 loop 45 | .Lshell_down_loop: 46 | ldrb r7, [r1, r6] 47 | ldr r10, [r0, r7, lsl #2] 48 | cmp r10, r9 @ fill[id] > key0 49 | ble .Lshell_down_loop_end 50 | strb r7, [r1, r5] @ PONDER: xxxgt? 51 | mov r5, r6 52 | subs r6, r5, r3 53 | bge .Lshell_down_loop 54 | .Lshell_down_loop_end: 55 | strb r8, [r1, r5] @ TODO: clean 56 | add r4, r4, #1 @ TODO: combine with ldrb 57 | cmp r4, r2 58 | blt .Lshell_up_loop 59 | .Lshell_up_loop_end: 60 | cmp r3, #1 61 | bgt .Lshell_inc_loop 62 | ldmfd sp!, {r4-r10} 63 | bx lr 64 | .align 2 65 | .Lshell_pool: 66 | .word 1431655766 67 | 68 | -------------------------------------------------------------------------------- /adv/m7_ex/source/mode7.c: -------------------------------------------------------------------------------- 1 | // 2 | // Mode 7 functions (ROM) 3 | // 4 | //! \file mode7.c 5 | //! \author J Vijn 6 | //! \date 20061111 - 20061121 7 | // 8 | // === NOTES === 9 | 10 | #include 11 | #include 12 | 13 | #include "mode7.h" 14 | 15 | 16 | // === CONSTANTS ====================================================== 17 | // === CLASSES ======================================================== 18 | // === GLOBALS ======================================================== 19 | 20 | 21 | // === FUNCTIONS ====================================================== 22 | 23 | void m7_init(M7_LEVEL *level, M7_CAM *cam, BG_AFFINE bgaff[], 24 | M7_SPRITE sprites[], u16 skycnt, u16 floorcnt) 25 | { 26 | level->camera= cam; 27 | level->bgaff= bgaff; 28 | level->sprites= sprites; 29 | level->bgcnt_sky= skycnt; 30 | level->bgcnt_floor= floorcnt; 31 | level->horizon= 80; 32 | 33 | REG_BG2CNT= floorcnt; 34 | REG_BG_AFFINE[2]= bg_aff_default; 35 | } 36 | 37 | //! Calculate the horizon scanline 38 | void m7_prep_horizon(M7_LEVEL *level) 39 | { 40 | int horz; 41 | M7_CAM *cam= level->camera; 42 | 43 | if(cam->v.y != 0) 44 | { 45 | #ifndef M7_HORZ_INFINITE 46 | horz= M7_FAR_BG*cam->w.y - cam->pos.y; 47 | horz= M7_TOP - Div(horz*M7_D, M7_FAR_BG*cam->v.y); 48 | #else 49 | horz= M7_TOP - Div(cam->w.y*M7_D, cam->v.y); 50 | #endif 51 | } 52 | else // looking straight down (w.y > 0) means horizon at -inf scanline 53 | horz= cam->w.y > 0 ? INT_MIN : INT_MAX; 54 | 55 | level->horizon= horz; 56 | } 57 | 58 | void m7_rotate(M7_CAM *cam, int phi, int theta) 59 | { 60 | theta= clamp(theta, -0x3FFF, 0x4001); 61 | cam->phi= phi; 62 | cam->theta= theta; 63 | 64 | FIXED cf, sf, ct, st; 65 | 66 | cf= lu_cos(phi)>>4; sf= lu_sin(phi)>>4; 67 | ct= lu_cos(theta)>>4; st= lu_sin(theta)>>4; 68 | 69 | // camera X-axis (right) 70 | cam->u.x= cf; 71 | cam->u.y= 0; 72 | cam->u.z= sf; 73 | 74 | // camera Y-axis (up) 75 | cam->v.x= sf*st>>8; 76 | cam->v.y= ct; 77 | cam->v.z= -cf*st>>8; 78 | 79 | // camera Z-axis (back) 80 | cam->w.x= -sf*ct>>8; 81 | cam->w.y= st; 82 | cam->w.z= cf*ct>>8; 83 | } 84 | 85 | //! Translate by \a dir using local frame for x/y, but global z 86 | void m7_translate_level(M7_CAM *cam, const VECTOR *dir) 87 | { 88 | cam->pos.x += (cam->u.x * dir->x - cam->u.z * dir->z)>>8; 89 | cam->pos.y += dir->y; 90 | cam->pos.z += (cam->u.z * dir->x + cam->u.x * dir->z)>>8; 91 | } 92 | 93 | //! Translate by \a dir in local frame 94 | void m7_translate_local(M7_CAM *cam, const VECTOR *dir) 95 | { 96 | // Operator overloading would be real nice right now :/ 97 | cam->pos.x += (cam->u.x * dir->x + cam->v.x * dir->y + cam->w.x * dir->z) >> 8; 98 | cam->pos.y += ( 0 + cam->v.y * dir->y + cam->w.y * dir->z) >> 8; 99 | cam->pos.z += (cam->u.z * dir->x + cam->v.z * dir->y + cam->w.z * dir->z) >> 8; 100 | } 101 | 102 | //! Translate by \a dir in global frame 103 | void m7_translate_global(M7_CAM *cam, const VECTOR *dir) 104 | { 105 | vec_add_eq(&cam->pos, dir); 106 | } 107 | 108 | //! Update sky-bg position 109 | void m7_update_sky(const M7_LEVEL *level) 110 | { 111 | REG_BG2HOFS= (level->camera->phi>>6)+M7_LEFT; 112 | REG_BG2VOFS= -m7_horizon_line(level)-1; 113 | } 114 | 115 | 116 | 117 | 118 | 119 | // EOF 120 | -------------------------------------------------------------------------------- /adv/m7_ex/source/mode7.h: -------------------------------------------------------------------------------- 1 | // 2 | // Mode 7 header file 3 | // 4 | //! \file mode7.c 5 | //! \author J Vijn 6 | //! \date 20061111 - 20061121 7 | // 8 | // === NOTES === 9 | 10 | #include 11 | 12 | #ifndef __MODE7__ 13 | #define __MODE7__ 14 | 15 | // === CONSTANTS ====================================================== 16 | 17 | // === CONSTANTS ====================================================== 18 | 19 | 20 | #define M7_D 256 //!< Focal length 21 | #define M7_D_SHIFT 8 //!< Focal shift 22 | #define M7O_NORM 2 //!< Object renormalization shift (by /4) 23 | 24 | // View frustrum limits 25 | #define M7_LEFT (-120) //!< Viewport left 26 | #define M7_RIGHT 120 //!< Viewport right 27 | #define M7_TOP 80 //!< Viewport top (y-axis up) 28 | #define M7_BOTTOM (-80) //!< Viewport bottom (y-axis up!) 29 | #define M7_NEAR 24 //!< Near plane (objects) 30 | #define M7_FAR 512 //!< Far plane (objects) 31 | 32 | #define M7_FAR_BG 768 //!< Far plane (floor) 33 | 34 | 35 | // === CLASSES ======================================================== 36 | 37 | //! 3D sprite struct 38 | typedef struct M7_SPRITE 39 | { 40 | VECTOR pos; //!< World position. 41 | POINT anchor; //!< Sprite anchor. 42 | OBJ_ATTR obj; //!< Object attributes. 43 | s16 phi; //!< Azimuth angle. 44 | u8 obj_id; //!< Object index. 45 | u8 aff_id; //!< OBJ_AFFINE index. 46 | TILE *tiles; //!< Gfx pointer. 47 | VECTOR pos2; //!< Position in cam space (subject to change) 48 | // To add: shade object 49 | } M7_SPRITE; 50 | 51 | //! 3D camera struct 52 | typedef struct M7_CAM 53 | { 54 | VECTOR pos; //!< World position. 55 | int theta; //!< Polar angle. 56 | int phi; //!< Azimuth angle. 57 | VECTOR u; //!< local x-axis (right) 58 | VECTOR v; //!< local y-axis (up) 59 | VECTOR w; //!< local z-axis (back) 60 | } M7_CAM; 61 | 62 | 63 | //! One struct to bind them all 64 | typedef struct M7_LEVEL 65 | { 66 | M7_CAM *camera; //!< Camera variables 67 | BG_AFFINE *bgaff; //!< Affine parameter array 68 | M7_SPRITE *sprites; //!< 3D sprites 69 | int horizon; //!< Horizon scanline (sorta) 70 | u16 bgcnt_sky; //!< BGxCNT for backdrop 71 | u16 bgcnt_floor; //!< BGxCNT for floor 72 | } M7_LEVEL; 73 | 74 | // === GLOBALS ======================================================== 75 | 76 | extern M7_LEVEL m7_level; 77 | 78 | // === PROTOTYPES ===================================================== 79 | 80 | void m7_init(M7_LEVEL *level, M7_CAM *cam, BG_AFFINE bg_aff[], 81 | M7_SPRITE sprites[], u16 skycnt, u16 floorcnt); 82 | void m7_prep_horizon(M7_LEVEL *level); 83 | void m7_update_sky(const M7_LEVEL *level); 84 | 85 | // Camera functions 86 | void m7_rotate(M7_CAM *cam, int theta, int phi); 87 | void m7_translate_level(M7_CAM *cam, const VECTOR *dir); 88 | void m7_translate_local(M7_CAM *cam, const VECTOR *dir); 89 | void m7_translate_global(M7_CAM *cam, const VECTOR *dir); 90 | 91 | 92 | INLINE int m7_horizon_line(const M7_LEVEL *level); 93 | 94 | // IWRAM functions 95 | IWRAM_CODE void m7_prep_affines(M7_LEVEL *level); 96 | IWRAM_CODE void m7_prep_sprite(M7_LEVEL *level, M7_SPRITE *spr); 97 | 98 | IWRAM_CODE void m7_hbl_floor(); 99 | 100 | // === INLINES========================================================= 101 | 102 | //! Get the scanline at which the horizon lies 103 | INLINE int m7_horizon_line(const M7_LEVEL *level) 104 | { return clamp(level->horizon, 0, 228); } 105 | 106 | #endif // __MODE7__ 107 | 108 | // EOF 109 | -------------------------------------------------------------------------------- /adv/m7_ex/source/mode7.iwram.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/m7_ex/source/mode7.iwram.c -------------------------------------------------------------------------------- /adv/tte_demo/fonts/cyber16.h: -------------------------------------------------------------------------------- 1 | 2 | //{{BLOCK(cyber16) 3 | 4 | #ifndef __CYBER16__ 5 | #define __CYBER16__ 6 | 7 | // Cybernator font, 8x16@4. Missing ascii have been added. 8 | 9 | extern const TFont cyber16Font; 10 | 11 | #define cyber16GlyphsLen 6144 12 | extern const unsigned int cyber16Glyphs[1536]; 13 | 14 | #define cyber16PalLen 32 15 | extern const unsigned short cyber16Pal[32]; 16 | 17 | #endif // __CYBER16__ 18 | 19 | //}}BLOCK(cyber16) 20 | -------------------------------------------------------------------------------- /adv/tte_demo/fonts/cyber16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/fonts/cyber16.png -------------------------------------------------------------------------------- /adv/tte_demo/fonts/fonts.h: -------------------------------------------------------------------------------- 1 | // 2 | // Font master header. 3 | // 4 | 5 | #ifndef __FONTS_H__ 6 | #define __FONTS_H__ 7 | 8 | #include "cyber16.h" 9 | #include "mssans9.h" 10 | #include "tahoma9.h" 11 | #include "verdana11.h" 12 | #include "yesh1.h" 13 | 14 | #endif // __FONTS_H__ 15 | 16 | // EOF 17 | -------------------------------------------------------------------------------- /adv/tte_demo/fonts/mssans9.h: -------------------------------------------------------------------------------- 1 | 2 | //{{BLOCK(mssans9) 3 | 4 | #ifndef __MSSANS9__ 5 | #define __MSSANS9__ 6 | 7 | // MicroSoft Sans Serif 9, 32-255, 1bpp 8 | 9 | extern const TFont mssans9Font; 10 | 11 | #define mssans9GlyphsLen 3584 12 | extern const unsigned int mssans9Glyphs[896]; 13 | 14 | #define mssans9WidthsLen 224 15 | extern const unsigned char mssans9Widths[224]; 16 | 17 | #endif // __MSSANS9__ 18 | 19 | //}}BLOCK(mssans9) 20 | -------------------------------------------------------------------------------- /adv/tte_demo/fonts/mssans9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/fonts/mssans9.png -------------------------------------------------------------------------------- /adv/tte_demo/fonts/tahoma9.h: -------------------------------------------------------------------------------- 1 | 2 | //{{BLOCK(tahoma9) 3 | 4 | #ifndef __TAHOMA9__ 5 | #define __TAHOMA9__ 6 | 7 | extern const TFont tahoma9Font; 8 | 9 | #define tahoma9GlyphsLen 3584 10 | extern const unsigned int tahoma9Glyphs[896]; 11 | 12 | #define tahoma9WidthsLen 224 13 | extern const unsigned char tahoma9Widths[224]; 14 | 15 | #endif // __TAHOMA9__ 16 | 17 | //}}BLOCK(tahoma9) 18 | -------------------------------------------------------------------------------- /adv/tte_demo/fonts/tahoma9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/fonts/tahoma9.png -------------------------------------------------------------------------------- /adv/tte_demo/fonts/verdana11.h: -------------------------------------------------------------------------------- 1 | 2 | //{{BLOCK(verdana11) 3 | 4 | #ifndef __VERDANA11__ 5 | #define __VERDANA11__ 6 | 7 | extern const TFont verdana11Font; 8 | 9 | #define verdana11GlyphsLen 3072 10 | extern const unsigned int verdana11Glyphs[768]; 11 | 12 | #define verdana11WidthsLen 96 13 | extern const unsigned char verdana11Widths[96]; 14 | 15 | #endif // __VERDANA11__ 16 | 17 | //}}BLOCK(verdana11) 18 | -------------------------------------------------------------------------------- /adv/tte_demo/fonts/verdana11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/fonts/verdana11.png -------------------------------------------------------------------------------- /adv/tte_demo/fonts/yesh1.h: -------------------------------------------------------------------------------- 1 | 2 | //{{BLOCK(yesh1) 3 | 4 | #ifndef __YESH1__ 5 | #define __YESH1__ 6 | 7 | // 4x8 Sub-pixel font by JanoS, http://www.haluz.org/yesh/ 8 | 9 | extern const TFont yesh1Font; 10 | 11 | #define yesh1GlyphsLen 6144 12 | extern const unsigned int yesh1Glyphs[1536]; 13 | 14 | #endif // __YESH1__ 15 | 16 | //}}BLOCK(yesh1) 17 | -------------------------------------------------------------------------------- /adv/tte_demo/fonts/yesh1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/fonts/yesh1.png -------------------------------------------------------------------------------- /adv/tte_demo/graphics/dlgbox.grit: -------------------------------------------------------------------------------- 1 | # 2 | # dlgbox tiles, column-major tile order. 3 | # 4 | # NOTE : with grit 0.8.1, column-major tiling can be done with -tc. 5 | # In older versions, you can fake it using -Mh(imgHeight/8). 6 | 7 | -gt -gB4 -pn16 -tc 8 | -------------------------------------------------------------------------------- /adv/tte_demo/graphics/dlgbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/graphics/dlgbox.png -------------------------------------------------------------------------------- /adv/tte_demo/graphics/dungeon01.grit: -------------------------------------------------------------------------------- 1 | # 2 | # LoZ:LttP, dungeon 1 map : 64x64t, 4bpp, SBB-layout, LZ77 compressed. 3 | # 4 | -gt -gB4 -mR4 -mLs -Zl 5 | -------------------------------------------------------------------------------- /adv/tte_demo/graphics/dungeon01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/graphics/dungeon01.png -------------------------------------------------------------------------------- /adv/tte_demo/graphics/menu_gfx.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Menu bitmap : 240x16@8, RLE 3 | # 4 | -gb -gB8 -gzr 5 | -------------------------------------------------------------------------------- /adv/tte_demo/graphics/menu_gfx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/tte_demo/graphics/menu_gfx.png -------------------------------------------------------------------------------- /adv/tte_demo/include/menu.h: -------------------------------------------------------------------------------- 1 | // 2 | // Basic function menu 3 | // 4 | //! \file menu.h 5 | //! \author J Vijn 6 | //! \date 20070926 - 20070926 7 | // 8 | /* === NOTES === 9 | */ 10 | 11 | 12 | #ifndef __MENU_H__ 13 | #define __MENU_H__ 14 | 15 | #include 16 | #include "menu.h" 17 | 18 | 19 | // -------------------------------------------------------------------- 20 | // CONSTANTS 21 | // -------------------------------------------------------------------- 22 | 23 | 24 | #define MENU_ACT_STD 0x00 //!< Standard run: wait/clear/desc/run. 25 | #define MENU_ACT_ALL 0x01 //!< Run all with waits between items. 26 | #define MENU_ACT_AUTO 0x02 //!< Run all without waits. 27 | //#define MENU_ACT_ALL 0x10 //!< Run all in sequence 28 | 29 | 30 | #define MENU_PAL_TEXT 0x09 31 | #define MENU_PAL_TYPE_BASE 0x0C 32 | #define MENU_PAL_INK 0x11 33 | #define MENU_PAL_SHADOW 0x12 34 | #define MENU_PAL_NOTE 0x13 35 | #define MENU_PAL_KEYW 0x14 36 | #define MENU_PAL_CMT 0x15 37 | #define MENU_PAL_STR 0x16 38 | #define MENU_PAL_TEXT_BASE 0x18 39 | 40 | #define MENU_CLR_WINDOW RGB15(25,25,25) 41 | #define MENU_CLR_TEXT RGB15( 4, 4, 4) 42 | #define MENU_CLR_OFF RGB15(16,16,16) 43 | #define MENU_CLR_INK RGB15(31,31, 0) 44 | #define MENU_CLR_SHADOW RGB15(31,16, 0) 45 | #define MENU_CLR_SEL RGB15(28, 8, 8) 46 | #define MENU_CLR_KEYW RGB15( 8,16,31) 47 | #define MENU_CLR_CMT RGB15( 8,24, 8) 48 | #define MENU_CLR_STR RGB15(24,8, 24) 49 | 50 | /* 51 | #define MENU_PAL_FRAME 16 52 | #define MENU_PAL_PAPER 17 53 | #define MENU_PAL_STD 18 54 | #define MENU_PAL_OFF 19 55 | #define MENU_PAL_SEL 20 56 | 57 | #define MENU_PAL_ITEM0 24 58 | 59 | #define MENU_CLR_FRAME RGB15(16,16,16) 60 | 61 | 62 | */ 63 | 64 | 65 | // -------------------------------------------------------------------- 66 | // TYPES 67 | // -------------------------------------------------------------------- 68 | 69 | 70 | typedef struct TMenuItem 71 | { 72 | const char *title; //!< Title for menu (short) 73 | const char *description; //!< Description 74 | void (*proc)(void); //!< Procedure for menu action (if any) 75 | u8 type; // 12 | 13 | #include 14 | #include "menu.h" 15 | #include "menu_gfx.h" 16 | 17 | const RECT cMenuMainRect= { 16, 16, 224, 128 }; 18 | const RECT cMenuPageRect= { 200, 138, 224, 150 }; 19 | 20 | 21 | void menu_act_clear(const TMenu *menu); 22 | void menu_act_description(const TMenu *menu); 23 | 24 | 25 | // -------------------------------------------------------------------- 26 | // FUNCTIONS 27 | // -------------------------------------------------------------------- 28 | 29 | //! Create the menu itself. 30 | void menu_create(TMenu *menu, const TMenuItem *items, u32 count) 31 | { 32 | 33 | menu->items= (TMenuItem*)items; 34 | menu->itemCount= count; 35 | menu->sel= 0; 36 | menu->state= MENU_ACT_STD; 37 | } 38 | 39 | //! Prepare for menu run (PONDER: incorporate in menu_run?). 40 | void menu_init(TMenu *menu) 41 | { 42 | int ii, nn; 43 | 44 | RegisterRamReset(RESET_GFX | RESET_REG_MASK); 45 | irq_init(NULL); 46 | irq_add(II_VBLANK, NULL); 47 | 48 | // --- Init graphic parts --- 49 | 50 | // Setup video mode, palette, text, VRAM 51 | // Graphic inits 52 | key_repeat_limits(40, 20); 53 | 54 | vid_page= vid_mem; 55 | tte_init_bmp_default(4); 56 | tte_init_con(); 57 | tte_set_ink(MENU_PAL_TEXT_BASE); 58 | 59 | // Init palette 60 | GRIT_CPY(pal_bg_mem, menu_gfxPal); 61 | pal_bg_mem[0]= CLR_BLACK; 62 | 63 | nn= min(8, menu->itemCount); 64 | for(ii=0; iisel, 0, menu->itemCount); 78 | menu->sel= sel; 79 | int page= sel>>3, selmax= menu->itemCount; 80 | 81 | // Run menu choices 82 | while(1) 83 | { 84 | VBlankIntrWait(); 85 | key_poll(); 86 | 87 | // Change run-type 88 | menu->state += KEY_TRIBOOL(key_hit, KI_R, KI_L); 89 | menu->state= wrap(menu->state, 0, 3); 90 | 91 | // move selection and act on move 92 | if(key_repeat(KEY_DOWN | KEY_UP)) 93 | { 94 | sel += KEY_TRIBOOL(key_repeat, KI_DOWN, KI_UP); 95 | sel = wrap(sel, 0, selmax); 96 | } 97 | else if(key_repeat(KEY_RIGHT | KEY_LEFT)) 98 | { 99 | sel += 8*KEY_TRIBOOL(key_repeat, KI_RIGHT, KI_LEFT); 100 | // page wrap 101 | sel= wrap(sel, 0, (selmax+7)&~7); 102 | if(sel >= selmax) 103 | sel= selmax-1; 104 | } 105 | 106 | menu->sel= sel; 107 | 108 | if(sel>>3 != page) 109 | { 110 | page= sel>>3; 111 | menu_draw(menu); 112 | } 113 | menu_update_page(menu); 114 | 115 | // if KEY_ACCEPT: break 116 | if(key_hit(KEY_ACCEPT)) 117 | break; 118 | } 119 | } 120 | 121 | //! Run the selected menu option(s). 122 | void menu_act(TMenu *menu) 123 | { 124 | TMenuItem *mi= &menu->items[menu->sel]; 125 | int ii, nn; 126 | 127 | if(mi->proc == NULL) 128 | return; 129 | 130 | switch(menu->state) 131 | { 132 | // Run one demo 133 | case MENU_ACT_STD: 134 | { 135 | menu_act_clear(menu); 136 | menu_act_description(menu); 137 | 138 | VBlankIntrDelay(5); 139 | mi->proc(); 140 | VBlankIntrDelay(5); 141 | break; 142 | } 143 | // Run all, without auto-timing at the description 144 | case MENU_ACT_ALL: //# TODO: create separate state for this 145 | case MENU_ACT_AUTO: 146 | { 147 | menu_act_clear(menu); 148 | nn= menu->itemCount; 149 | 150 | for(ii=0; iisel= ii; 153 | mi= &menu->items[menu->sel]; 154 | 155 | if(mi->proc == NULL) 156 | continue; 157 | 158 | menu_act_description(menu); 159 | 160 | VBlankIntrDelay(5); 161 | mi->proc(); 162 | VBlankIntrDelay(5); 163 | } 164 | } 165 | } 166 | } 167 | 168 | //! Draw the whole menu 169 | void menu_draw(const TMenu *menu) 170 | { 171 | int ii, nn, page; 172 | 173 | RLUnCompVram(menu_gfxBitmap, vid_page); 174 | 175 | // Draw page 176 | page= menu->sel/8; 177 | nn= min(8, menu->itemCount-page*8); 178 | TMenuItem *mi= &menu->items[page*8]; 179 | 180 | // Plot item strings 181 | for(ii=0; iiitemCount+7)/8); 192 | POINT16 pt= tte_get_text_size(str); 193 | tte_printf("#{P:%d,138;ci:%d}%s", cMenuPageRect.right-pt.x, 194 | MENU_PAL_TEXT, str); 195 | } 196 | 197 | //! Update the page for colors 198 | void menu_update_page(const TMenu *menu) 199 | { 200 | int ii, nn, page; 201 | 202 | // Update menu items 203 | page= menu->sel/8; 204 | nn= min(8, menu->itemCount-page*8); 205 | for(ii=0; iistate==ii ? MENU_CLR_SEL : MENU_CLR_TEXT; 212 | } 213 | 214 | 215 | //! Draw menu item (kinda; switches palettes to match options currently) 216 | void menu_update_item(const TMenu *menu, int sel) 217 | { 218 | if(sel >= menu->itemCount) 219 | return; 220 | 221 | COLOR *clr= &pal_bg_mem[MENU_PAL_TEXT_BASE+(sel&7)]; 222 | 223 | if(menu->items[sel].proc == NULL) 224 | { 225 | *clr= MENU_CLR_OFF; 226 | return; 227 | } 228 | 229 | *clr= (menu->sel == sel) ? MENU_CLR_SEL : MENU_CLR_TEXT; 230 | } 231 | 232 | 233 | void menu_act_clear(const TMenu *menu) 234 | { 235 | int ii, nn, page; 236 | 237 | // clear other menu items 238 | page = menu->sel/8; 239 | nn= min(8, menu->itemCount-page*8); 240 | COLOR *clr= &pal_bg_mem[MENU_PAL_TEXT_BASE]; 241 | 242 | for(ii=0; iisel == page*8+ii) ? MENU_CLR_SEL : MENU_CLR_WINDOW; 244 | 245 | VBlankIntrDelay(15); 246 | m4_fill(0); 247 | VBlankIntrDelay(15); 248 | } 249 | 250 | 251 | //! Handle description stage 252 | void menu_act_description(const TMenu *menu) 253 | { 254 | TMenuItem *mi= &menu->items[menu->sel]; 255 | 256 | if(!mi->description) 257 | return; 258 | 259 | VBlankIntrWait(); 260 | 261 | // --- (re)-init gfx for description --- 262 | if(menu->state != MENU_ACT_STD) 263 | { 264 | RegisterRamReset(RESET_GFX); 265 | // Erase gfx registers (but not REG_DISPSTAT. That apparently 266 | // would be bad) 267 | memset32((void*)REG_BGCNT, 0, 0x58/4); 268 | 269 | REG_BG_AFFINE[2]= bg_aff_default; 270 | 271 | vid_page= vid_mem; 272 | tte_init_bmp_default(4); 273 | tte_init_con(); 274 | 275 | // Init palette 276 | GRIT_CPY(pal_bg_mem, menu_gfxPal); 277 | pal_bg_mem[0]= CLR_BLACK; 278 | 279 | REG_DISPCNT= DCNT_MODE4 | DCNT_BG2; 280 | } 281 | 282 | // --- Run description --- 283 | 284 | VBlankIntrWait(); 285 | 286 | tte_set_margins(8,8, SCR_W-8, SCR_H-8); 287 | tte_set_font(&verdana9bFont); 288 | tte_printf("#{P;ci:" XSTR(MENU_PAL_KEYW) "}%s", mi->title); 289 | tte_set_font(&vwf_default); 290 | tte_printf("#{P:8,20;ci:" XSTR(MENU_PAL_INK) "}%s",mi->description); 291 | tte_set_margins(0, 0, SCR_W, SCR_H); 292 | 293 | if(menu->state == MENU_ACT_AUTO) 294 | { 295 | u32 len= max(strlen(mi->description), 60); 296 | VBlankIntrDelay(len); 297 | } 298 | else 299 | { 300 | while(1) 301 | { 302 | VBlankIntrWait(); 303 | key_poll(); 304 | if(key_hit(KEY_ANY)) 305 | break; 306 | } 307 | } 308 | 309 | RegisterRamReset(RESET_GFX); 310 | } 311 | 312 | // EOF 313 | -------------------------------------------------------------------------------- /adv/txt_bm/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /adv/txt_bm/source/txt_bm.c: -------------------------------------------------------------------------------- 1 | // 2 | //! \file txt_bm.c 3 | //! Bitmap text demo (modes 3,4,5) 4 | //! \date 20051009 - 20060930 5 | //! \author cearn 6 | // 7 | // === NOTES === 8 | // * The current mode is indicated by the readable "mode 3", 9 | // "mode 4" or "mode 5". The cursor position is displayed in white. 10 | // * D-pad: moves cursor. 11 | // * L,R: switches between modes 12 | // * Start: toggles cursor-string 'opacity' (i.e, between direct 13 | // overwrite and clear+overwrite) 14 | 15 | #include 16 | #include 17 | 18 | #define LEGACY_TEXT_V11 19 | #include 20 | 21 | 22 | // -------------------------------------------------------------------- 23 | // CONSTANTS 24 | // -------------------------------------------------------------------- 25 | 26 | #define CLR_BD 0x080F 27 | 28 | const TILE cursorTile= 29 | {{ 0x0, 0x21, 0x211, 0x2111, 0x21111, 0x2100, 0x1100, 0x21000 }}; 30 | 31 | 32 | // -------------------------------------------------------------------- 33 | // FUNCTIONS 34 | // -------------------------------------------------------------------- 35 | 36 | 37 | void init_main() 38 | { 39 | vid_page= vid_mem; 40 | 41 | // init interrupts 42 | irq_init(NULL); 43 | irq_add(II_VBLANK, NULL); 44 | 45 | // init backdrop 46 | pal_bg_mem[0]= CLR_MAG; 47 | pal_bg_mem[CLR_BD>>8]= CLR_BD; 48 | pal_bg_mem[CLR_BD&255]= CLR_BD; 49 | m3_fill(CLR_BD); 50 | 51 | // init mode 4 pal 52 | pal_bg_mem[1]= CLR_LIME; 53 | pal_bg_mem[255]= CLR_WHITE; 54 | 55 | // init cursor 56 | tile_mem[5][0]= cursorTile; 57 | pal_obj_mem[1]= CLR_WHITE; 58 | pal_obj_mem[2]= CLR_GRAY; 59 | } 60 | 61 | int main() 62 | { 63 | init_main(); 64 | 65 | txt_init_std(); 66 | 67 | // print some string so we know what mode we're at 68 | m3_puts(8, 8, "mode 3", CLR_CYAN); 69 | m4_puts(12, 32, "mode 4", 1); 70 | m5_puts(16, 40, "mode 5", CLR_YELLOW); 71 | 72 | // init variables 73 | u32 mode=3, bClear=0; 74 | OBJ_ATTR cursor= { 80, 120, 512, 0 }; 75 | 76 | // init video mode 77 | REG_DISPCNT= DCNT_BG2 | DCNT_OBJ | 3; 78 | 79 | // init cursor string 80 | char str[32]; 81 | siprintf(str, "o %3d,%3d", cursor.attr1, cursor.attr0); 82 | 83 | while(1) 84 | { 85 | VBlankIntrWait(); 86 | 87 | oam_mem[0]= cursor; 88 | key_poll(); 89 | 90 | if(key_hit(KEY_START)) 91 | bClear ^= 1; 92 | 93 | // move cursor 94 | cursor.attr1 += key_tri_horz(); 95 | cursor.attr0 += key_tri_vert(); 96 | 97 | // adjust cursor(-string) only if necessary 98 | if(key_is_down(KEY_ANY)) 99 | { 100 | if(bClear) 101 | bm_clrs(80, 112, str, CLR_BD); 102 | 103 | cursor.attr0 &= ATTR0_Y_MASK; 104 | cursor.attr1 &= ATTR1_X_MASK; 105 | siprintf(str, "%c %3d,%3d", (bClear?'c':'o'), 106 | cursor.attr1, cursor.attr0); 107 | } 108 | 109 | // switch modes 110 | mode += bit_tribool(key_hit(-1), KI_R, KI_L); 111 | mode= clamp(mode, 3, 6); 112 | 113 | BFN_SET(REG_DISPCNT, mode, DCNT_MODE); 114 | 115 | bm_puts(80, 112, str, CLR_WHITE); 116 | } 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /adv/txt_obj/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /adv/txt_obj/source/txt_obj.c: -------------------------------------------------------------------------------- 1 | // 2 | //! \file txt_obj.c 3 | //! Object text demo 4 | //! \date 20051028 - 20060930 5 | //! \author cearn 6 | // 7 | // === NOTES === 8 | // * Yes I know it contains 'hidden' bugs, but sorting them out would 9 | // just complicate the code to no end and isn't worth the bother. 10 | 11 | #include 12 | 13 | #define LEGACY_TEXT_V11 14 | #include 15 | 16 | 17 | // -------------------------------------------------------------------- 18 | // CONSTANTS & STRUCTS 19 | // -------------------------------------------------------------------- 20 | 21 | 22 | #define POS0 (80<<8) 23 | #define GRAV 0x40 24 | #define DAMP 0xD0 25 | #define HWLEN 12 26 | 27 | const char hwstr[]= "Hello world!"; 28 | 29 | typedef struct 30 | { 31 | u32 state; 32 | int tt; 33 | FIXED fy; 34 | FIXED fvy; 35 | } PATTERN; 36 | 37 | 38 | // -------------------------------------------------------------------- 39 | // FUNCTIONS 40 | // -------------------------------------------------------------------- 41 | 42 | 43 | void pat_bounce(PATTERN *pat) 44 | { 45 | if(pat->tt <= 0) // timer's run out: play pattern 46 | { 47 | pat->fvy += GRAV; 48 | pat->fy += pat->fvy; 49 | 50 | // touched floor: bounce 51 | if(pat->fy > POS0) 52 | { 53 | // damp if we still have enough speed 54 | // otherwise kill movement 55 | if(pat->fvy > DAMP) 56 | { 57 | pat->fy= 2*POS0-pat->fy; 58 | pat->fvy= DAMP-pat->fvy; 59 | } 60 | else 61 | { 62 | pat->fy= POS0; 63 | pat->fvy= 0; 64 | } 65 | } 66 | } 67 | else // still in waiting period 68 | pat->tt--; 69 | } 70 | 71 | int main() 72 | { 73 | REG_DISPCNT= DCNT_MODE3 | DCNT_BG2 | DCNT_OBJ; 74 | 75 | irq_init(NULL); 76 | irq_add(II_VBLANK, NULL); 77 | memset16(&vid_mem[88*240], CLR_GREEN, 240); 78 | 79 | // init sprite text 80 | txt_init_std(); 81 | txt_init_obj(oam_mem, 0xF200, CLR_YELLOW, 0x0E); 82 | // 12 px between letters 83 | gptxt->dx= 12; 84 | 85 | // init sprite letters 86 | OBJ_ATTR *obj= oam_mem; 87 | obj_puts2(120-12*HWLEN/2, 8, hwstr, 0xF200, obj); 88 | 89 | int ii; 90 | PATTERN pats[HWLEN]; 91 | 92 | for(ii=0; ii>8)& ATTR0_Y_MASK; 115 | } 116 | } 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /adv/txt_se1/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /adv/txt_se1/border-original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/txt_se1/border-original.png -------------------------------------------------------------------------------- /adv/txt_se1/graphics/border.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Border : 4bpp, 16 colors, not compressed. 3 | # 4 | -gt -gB4 -pn16 -gT6BADBD 5 | -------------------------------------------------------------------------------- /adv/txt_se1/graphics/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/txt_se1/graphics/border.png -------------------------------------------------------------------------------- /adv/txt_se1/source/txt_se1.c: -------------------------------------------------------------------------------- 1 | // 2 | //! \file txt_se1.c 3 | //! Screen-entry text demo 4 | //! \date 20051128 - 20060930 5 | //! \author cearn 6 | // 7 | // === NOTES === 8 | // 9 | // Modified in 20221114 by AntonioND to fix palette issues. 10 | 11 | #include 12 | 13 | #define LEGACY_TEXT_V11 14 | #include 15 | 16 | #include "border.h" 17 | 18 | 19 | // -------------------------------------------------------------------- 20 | // CONSTANTS & STRUCTS 21 | // -------------------------------------------------------------------- 22 | 23 | 24 | #define TID_FRAME0 96 25 | #define TID_FRAME1 105 26 | #define TID_FONT 0 27 | #define TID_FONT2 128 28 | #define TID_FONT3 256 29 | #define TXT_PID_SHADE 0xEE 30 | #define TXT_PID_BG 0x88 31 | 32 | 33 | // -------------------------------------------------------------------- 34 | // FUNCTIONS 35 | // -------------------------------------------------------------------- 36 | 37 | 38 | void init_main() 39 | { 40 | int ii; 41 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 42 | 43 | irq_init(NULL); 44 | irq_add(II_VBLANK, NULL); 45 | 46 | txt_init_std(); 47 | txt_init_se(0, BG_CBB(0) | BG_SBB(31), 0x1000, CLR_RED, 0x0E); 48 | 49 | // again, with a twist 50 | txt_init_se(0, BG_CBB(0) | BG_SBB(31), 0xF000|TID_FONT2, 51 | CLR_YELLOW | (CLR_MAG<<16), TXT_PID_SHADE); 52 | 53 | // and once more, with feeling! 54 | txt_init_se(0, BG_CBB(0) | BG_SBB(31), 0xE000|TID_FONT3, 55 | 0, TXT_PID_SHADE); 56 | u32 *pwd= (u32*)&tile_mem[0][TID_FONT3]; 57 | for(ii=0; ii<96*8; ii++) 58 | *pwd++ |= quad8(TXT_PID_BG); 59 | 60 | // extra border initialisation 61 | memcpy32(&tile_mem[0][TID_FRAME0], borderTiles, borderTilesLen/4); 62 | memcpy32(pal_bg_mem, borderPal, borderPalLen/4); 63 | 64 | // overwrite /\ [] `% ^_ to use border tiles 65 | // / ^ \ 66 | // [ # ] 67 | // ` _ ' 68 | const u8 bdr_lut[9]= "/^\\[#]`_\'"; 69 | for(ii=0; ii<9; ii++) 70 | gptxt->chars[bdr_lut[ii]]= TID_FRAME0+ii; 71 | 72 | // set some extra colors 73 | pal_bg_mem[0x1F]= CLR_RED; 74 | pal_bg_mem[0x2F]= CLR_GREEN; 75 | pal_bg_mem[0x3F]= CLR_BLUE; 76 | pal_bg_mem[0x4F]= CLR_WHITE; 77 | 78 | pal_bg_mem[0xE8]= RGB15(0, 0, 24); // bg 79 | pal_bg_mem[0xEE]= CLR_ORANGE; // shadow 80 | pal_bg_mem[0xEF]= CLR_WHITE; // text 81 | } 82 | 83 | void txt_se_frame(int l, int t, int r, int b, u16 se0) 84 | { 85 | int ix, iy; 86 | u8 *lut= gptxt->chars; 87 | u16 *pse= (u16*)gptxt->dst0; 88 | pse += t*32 + l; 89 | r -= (l+1); 90 | b -= (t+1); 91 | 92 | // corners 93 | pse[32*0 + 0] = se0+lut['/']; 94 | pse[32*0 + r] = se0+lut['\\']; 95 | pse[32*b + 0] = se0+lut['`']; 96 | pse[32*b + r] = se0+lut['\'']; 97 | 98 | // horizontal 99 | for(ix=1; ixdevkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /adv/txt_se2/graphics/gba_pic.grit: -------------------------------------------------------------------------------- 1 | # 2 | # GBA : bitmap, 8bpp, flat-layout, not compressed. 3 | # 4 | -gb -gB8 -m -mLf 5 | -------------------------------------------------------------------------------- /adv/txt_se2/graphics/gba_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/adv/txt_se2/graphics/gba_pic.png -------------------------------------------------------------------------------- /adv/txt_se2/source/txt_se2.c: -------------------------------------------------------------------------------- 1 | // 2 | //! \file txt_se2.c 3 | //! Screen entry text demo 4 | //! \date 20051028 - 20060103 5 | //! \author cearn 6 | // 7 | // === NOTES === 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #define LEGACY_TEXT_V11 16 | #include 17 | 18 | #include "gba_pic.h" 19 | 20 | // -------------------------------------------------------------------- 21 | // CONSTANTS & STRUCTS 22 | // -------------------------------------------------------------------- 23 | 24 | 25 | int gtimes[5]; 26 | 27 | const char *strs[5]= 28 | { "u16 array", "u32 array", "memcpy", "memcpy32", "DMA32" }; 29 | 30 | // hw : 674978, 260299, 195171, 86846, 76902 31 | // no$: 672162, 259309, 194608, 85283, 76901 32 | // vba: 557081, 192183, 160367, 80049, 222 33 | 34 | 35 | // -------------------------------------------------------------------- 36 | // FUNCTIONS 37 | // -------------------------------------------------------------------- 38 | 39 | 40 | // copy via u16 array 41 | void test_0(u16 *dst, const u16 *src, u32 len) 42 | { 43 | u32 ii; 44 | profile_start(); 45 | for(ii=0; iidevkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/gba_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves 13 | #--------------------------------------------------------------------------------- 14 | LIBTONC := $(DEVKITPRO)/libtonc 15 | 16 | #--------------------------------------------------------------------------------- 17 | # TARGET is the name of the output 18 | # BUILD is the directory where object files & intermediate files will be placed 19 | # SOURCES is a list of directories containing source code 20 | # INCLUDES is a list of directories containing extra header files 21 | # DATA is a list of directories containing binary data 22 | # GRAPHICS is a list of directories containing files to be processed by grit 23 | # 24 | # All directories are specified relative to the project directory where 25 | # the makefile is found 26 | # 27 | #--------------------------------------------------------------------------------- 28 | TARGET := $(notdir $(CURDIR)) 29 | BUILD := build 30 | SOURCES := source 31 | INCLUDES := include 32 | DATA := 33 | MUSIC := 34 | GRAPHICS := graphics 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | ARCH := -mthumb -mthumb-interwork 40 | 41 | CFLAGS := -g -Wall -O2\ 42 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 43 | $(ARCH) 44 | 45 | CFLAGS += $(INCLUDE) 46 | 47 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 48 | 49 | ASFLAGS := -g $(ARCH) 50 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) 51 | 52 | #--------------------------------------------------------------------------------- 53 | # any extra libraries we wish to link with the project 54 | #--------------------------------------------------------------------------------- 55 | LIBS := -lmm -ltonc 56 | 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib. 61 | # the LIBGBA path should remain in this list if you want to use maxmod 62 | #--------------------------------------------------------------------------------- 63 | LIBDIRS := $(LIBGBA) $(LIBTONC) 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | 70 | 71 | ifneq ($(BUILD),$(notdir $(CURDIR))) 72 | #--------------------------------------------------------------------------------- 73 | 74 | export OUTPUT := $(CURDIR)/$(TARGET) 75 | 76 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 77 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 78 | $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) 79 | 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 83 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 84 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 85 | PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) 86 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 87 | 88 | ifneq ($(strip $(MUSIC)),) 89 | export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) 90 | BINFILES += soundbank.bin 91 | endif 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | #--------------------------------------------------------------------------------- 98 | export LD := $(CC) 99 | #--------------------------------------------------------------------------------- 100 | else 101 | #--------------------------------------------------------------------------------- 102 | export LD := $(CXX) 103 | #--------------------------------------------------------------------------------- 104 | endif 105 | #--------------------------------------------------------------------------------- 106 | 107 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 108 | 109 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 110 | 111 | export OFILES_GRAPHICS := $(PNGFILES:.png=.o) 112 | 113 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_GRAPHICS) 114 | 115 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) 116 | 117 | export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ 118 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 119 | -I$(CURDIR)/$(BUILD) 120 | 121 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 122 | 123 | .PHONY: $(BUILD) clean 124 | 125 | #--------------------------------------------------------------------------------- 126 | $(BUILD): 127 | @[ -d $@ ] || mkdir -p $@ 128 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 129 | 130 | #--------------------------------------------------------------------------------- 131 | clean: 132 | @echo clean ... 133 | @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba 134 | 135 | 136 | #--------------------------------------------------------------------------------- 137 | else 138 | 139 | #--------------------------------------------------------------------------------- 140 | # main targets 141 | #--------------------------------------------------------------------------------- 142 | 143 | $(OUTPUT).gba : $(OUTPUT).elf 144 | 145 | $(OUTPUT).elf : $(OFILES) 146 | 147 | $(OFILES_SOURCES) : $(HFILES) 148 | 149 | #--------------------------------------------------------------------------------- 150 | # The bin2o rule should be copied and modified 151 | # for each extension used in the data directories 152 | #--------------------------------------------------------------------------------- 153 | 154 | #--------------------------------------------------------------------------------- 155 | # rule to build soundbank from music files 156 | #--------------------------------------------------------------------------------- 157 | soundbank.bin soundbank.h : $(AUDIOFILES) 158 | #--------------------------------------------------------------------------------- 159 | @mmutil $^ -osoundbank.bin -hsoundbank.h 160 | 161 | #--------------------------------------------------------------------------------- 162 | # This rule links in binary data with the .bin extension 163 | #--------------------------------------------------------------------------------- 164 | %.bin.o %_bin.h : %.bin 165 | #--------------------------------------------------------------------------------- 166 | @echo $(notdir $<) 167 | @$(bin2o) 168 | 169 | #--------------------------------------------------------------------------------- 170 | # This rule creates assembly source files using grit 171 | # grit takes an image file and a .grit describing how the file is to be processed 172 | # add additional rules like this for each image extension 173 | # you use in the graphics folders 174 | #--------------------------------------------------------------------------------- 175 | %.s %.h: %.png %.grit 176 | #--------------------------------------------------------------------------------- 177 | @echo "grit $(notdir $<)" 178 | @grit $< -fts -o$* 179 | 180 | # make likes to delete intermediate files. This prevents it from deleting the 181 | # files generated by grit after building the GBA ROM. 182 | .SECONDARY: 183 | 184 | -include $(DEPSDIR)/*.d 185 | #--------------------------------------------------------------------------------------- 186 | endif 187 | #--------------------------------------------------------------------------------------- 188 | -------------------------------------------------------------------------------- /basic/bm_modes/graphics/modes.grit: -------------------------------------------------------------------------------- 1 | # 16 bpp bitmap 2 | -gb -gB16 3 | -------------------------------------------------------------------------------- /basic/bm_modes/graphics/modes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/bm_modes/graphics/modes.png -------------------------------------------------------------------------------- /basic/bm_modes/graphics/modes_pal.grit: -------------------------------------------------------------------------------- 1 | # Treat the bitmap as a 8 BPP image and only export the palette 2 | -gB8 -g! -p 3 | -------------------------------------------------------------------------------- /basic/bm_modes/graphics/modes_pal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/bm_modes/graphics/modes_pal.png -------------------------------------------------------------------------------- /basic/bm_modes/source/bm_modes.c: -------------------------------------------------------------------------------- 1 | // 2 | // bm_modes.c 3 | // Combined demo of modes 3, 4 and 5 4 | // 5 | // (20031002 - 20060922, cearn) 6 | 7 | // This example is a hack. Normally you aren't supposed to have a bitmap that is 8 | // used in different modes. Modes 3 and 5 use 16 BPP images so they could, in 9 | // theory, share graphics. However, mode 4 uses 8 BPP images. 10 | 11 | #include 12 | #include 13 | #include "modes.h" 14 | #include "modes_pal.h" 15 | 16 | int main() 17 | { 18 | int mode= 3; 19 | REG_DISPCNT= mode | DCNT_BG2; 20 | 21 | // Copy the data and palette to the right 22 | // addresses 23 | memcpy32(vid_mem, modesBitmap, modesBitmapLen / sizeof(u32)); 24 | memcpy16(pal_bg_mem, modes_palPal, modes_palPalLen / sizeof(u16)); 25 | 26 | while(1) 27 | { 28 | // Wait till VBlank before doing anything 29 | vid_vsync(); 30 | 31 | // Check keys for mode change 32 | key_poll(); 33 | if(key_hit(KEY_LEFT) && mode>3) 34 | mode--; 35 | else if(key_hit(KEY_RIGHT) && mode<5) 36 | mode++; 37 | 38 | // Change the mode 39 | REG_DISPCNT= mode | DCNT_BG2; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /basic/brin_demo/graphics/brin.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Brinstar : 64x64t, 4bpp, SBB-layout, not compressed. 3 | # 4 | -gt -gB4 -mR4 -mLs 5 | -------------------------------------------------------------------------------- /basic/brin_demo/graphics/brin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/brin_demo/graphics/brin.png -------------------------------------------------------------------------------- /basic/brin_demo/source/brin_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // brin_demo.c 3 | // Essential tilemap loading: the start of brinstar from metroid 1 4 | // 5 | // (20060221 - 20070216, cearn) 6 | 7 | #include 8 | 9 | #include 10 | #include "brin.h" 11 | 12 | int main() 13 | { 14 | // Load palette 15 | memcpy16(pal_bg_mem, brinPal, brinPalLen / sizeof(u16)); 16 | // Load tiles into CBB 0 17 | memcpy32(&tile_mem[0][0], brinTiles, brinTilesLen / sizeof(u32)); 18 | // Load map into SBB 30 19 | memcpy32(&se_mem[30][0], brinMap, brinMapLen / sizeof(u32)); 20 | 21 | // set up BG0 for a 4bpp 64x32t map, using 22 | // using charblock 0 and screenblock 31 23 | REG_BG0CNT= BG_CBB(0) | BG_SBB(30) | BG_4BPP | BG_REG_64x32; 24 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 25 | 26 | // Scroll around some 27 | int x= 192, y= 64; 28 | while(1) 29 | { 30 | vid_vsync(); 31 | key_poll(); 32 | 33 | x += key_tri_horz(); 34 | y += key_tri_vert(); 35 | 36 | REG_BG0HOFS= x; 37 | REG_BG0VOFS= y; 38 | } 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /basic/cbb_demo/cbb_ids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/cbb_demo/cbb_ids.png -------------------------------------------------------------------------------- /basic/cbb_demo/source/cbb_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // cbb_demo.c 3 | // showing char-block boundaries for 4 and 8-bit tile-maps 4 | // 5 | // (20031114 - 20060924, cearn) 6 | 7 | #include 8 | 9 | #include "cbb_ids.h" 10 | 11 | #define CBB_4 0 12 | #define SBB_4 2 13 | 14 | #define CBB_8 2 15 | #define SBB_8 4 16 | 17 | void load_tiles() 18 | { 19 | int ii; 20 | TILE *tl= (TILE*)ids4Tiles; 21 | TILE8 *tl8= (TILE8*)ids8Tiles; 22 | 23 | // Loading tiles. don't get freaked out on how it looks 24 | // 4-bit tiles to blocks 0 and 1 25 | tile_mem[0][1]= tl[1]; tile_mem[0][2]= tl[2]; 26 | tile_mem[1][0]= tl[3]; tile_mem[1][1]= tl[4]; 27 | // and the 8-bit tiles to blocks 2 though 5 28 | tile8_mem[2][1]= tl8[1]; tile8_mem[2][2]= tl8[2]; 29 | tile8_mem[3][0]= tl8[3]; tile8_mem[3][1]= tl8[4]; 30 | tile8_mem[4][0]= tl8[5]; tile8_mem[4][1]= tl8[6]; 31 | tile8_mem[5][0]= tl8[7]; tile8_mem[5][1]= tl8[8]; 32 | 33 | // And let's not forget the palette (yes, obj pal too) 34 | u16 *src= (u16*)ids4Pal; 35 | for(ii=0; ii<16; ii++) 36 | pal_bg_mem[ii]= pal_obj_mem[ii]= *src++; 37 | } 38 | 39 | void init_maps() 40 | { 41 | // se4 and se8 map coords: (0,2) and (0,8) 42 | SCR_ENTRY *se4= &se_mem[SBB_4][2*32], *se8= &se_mem[SBB_8][8*32]; 43 | // show first tiles of char-blocks available to bg0 44 | // tiles 1, 2 of char-block CBB_4 45 | se4[0x01]= 0x0001; se4[0x02]= 0x0002; 46 | 47 | // tiles 0, 1 of char-block CBB_4+1 48 | se4[0x20]= 0x0200; se4[0x21]= 0x0201; 49 | 50 | // show first tiles of char-blocks available to bg1 51 | // tiles 1, 2 of char-block CBB_8 (== 2) 52 | se8[0x01]= 0x0001; se8[0x02]= 0x0002; 53 | 54 | // tiles 1, 2 of char-block CBB_8+1 55 | se8[0x20]= 0x0100; se8[0x21]= 0x0101; 56 | 57 | // tiles 1, 2 of char-block CBB_8+2 (== CBB_OBJ_LO) 58 | se8[0x40]= 0x0200; se8[0x41]= 0x0201; 59 | 60 | // tiles 1, 2 of char-block CBB_8+3 (== CBB_OBJ_HI) 61 | se8[0x60]= 0x0300; se8[0x61]= 0x0301; 62 | } 63 | 64 | int main() 65 | { 66 | load_tiles(); 67 | init_maps(); 68 | 69 | // init backgrounds 70 | REG_BG0CNT= BG_CBB(CBB_4) | BG_SBB(SBB_4) | BG_4BPP; 71 | REG_BG1CNT= BG_CBB(CBB_8) | BG_SBB(SBB_8) | BG_8BPP; 72 | // enable backgrounds 73 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_OBJ; 74 | 75 | while(1); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /basic/cbb_demo/source/cbb_ids.c: -------------------------------------------------------------------------------- 1 | //====================================================================== 2 | // 3 | // ids8, 72x8@8, 4 | // + 9 tiles not compressed 5 | // Total size: 576 = 576 6 | // 7 | // Time-stamp: 2005-12-24, 18:28:50 8 | // Exported by Cearn's Usenti v1.7.1 9 | // (comments, kudos, flames to "daytshen@hotmail.com") 10 | // 11 | //====================================================================== 12 | 13 | const unsigned int ids8Tiles[144]= 14 | { 15 | 0x00000000,0x00000000,0x00000000,0x00000000,0x000D0D00,0x00000000,0x0D000000,0x00000000, 16 | 0x000D0000,0x00000000,0x00000D00,0x00000000,0x0D0D0D00,0x00000000,0x00000000,0x00000000, 17 | 0x00000000,0x00000000,0x00000000,0x00000000,0x000D0D00,0x000A0A00,0x0D000000,0x000A0000, 18 | 0x000D0000,0x000A0000,0x00000D00,0x000A0000,0x0D0D0D00,0x0A0A0A00,0x00000000,0x00000000, 19 | 0x00000000,0x00000000,0x00000000,0x00000000,0x000D0D00,0x000A0A00,0x0D000000,0x0A000000, 20 | 0x000D0000,0x000A0000,0x00000D00,0x00000A00,0x0D0D0D00,0x0A0A0A00,0x00000000,0x00000000, 21 | 0x00000000,0x00000000,0x00000000,0x00000000,0x000D0D00,0x000A0000,0x0D000000,0x0A000A00, 22 | 0x000D0000,0x0A000A00,0x0D000000,0x0A000A00,0x000D0D00,0x000A0000,0x00000000,0x00000000, 23 | 24 | 0x00000000,0x00000000,0x00000000,0x00000000,0x000D0D00,0x000A0A00,0x0D000000,0x000A0000, 25 | 0x000D0000,0x000A0000,0x0D000000,0x000A0000,0x000D0D00,0x0A0A0A00,0x00000000,0x00000000, 26 | 0x00000000,0x00000000,0x00000000,0x00000000,0x0D000D00,0x000A0000,0x0D000D00,0x0A000A00, 27 | 0x0D0D0D00,0x0A000A00,0x0D000000,0x0A000A00,0x0D000000,0x000A0000,0x00000000,0x00000000, 28 | 0x00000000,0x00000000,0x00000000,0x00000000,0x0D000D00,0x000A0A00,0x0D000D00,0x000A0000, 29 | 0x0D0D0D00,0x000A0000,0x0D000000,0x000A0000,0x0D000000,0x0A0A0A00,0x00000000,0x00000000, 30 | 0x00000000,0x00000000,0x00000000,0x00000000,0x0D0D0D00,0x000A0000,0x00000D00,0x0A000A00, 31 | 0x000D0D00,0x0A000A00,0x0D000000,0x0A000A00,0x000D0D00,0x000A0000,0x00000000,0x00000000, 32 | 33 | 0x00000000,0x00000000,0x00000000,0x00000000,0x0D0D0D00,0x000A0A00,0x00000D00,0x000A0000, 34 | 0x000D0D00,0x000A0000,0x0D000000,0x000A0000,0x000D0D00,0x0A0A0A00,0x00000000,0x00000000, 35 | }; 36 | 37 | //====================================================================== 38 | // 39 | // ids4, 40x8@4, 40 | // + palette 16 entries, not compressed 41 | // + 5 tiles not compressed 42 | // Total size: 32 + 160 = 192 43 | // 44 | // Time-stamp: 2005-12-24, 18:29:30 45 | // Exported by Cearn's Usenti v1.7.1 46 | // (comments, kudos, flames to "daytshen@hotmail.com") 47 | // 48 | //====================================================================== 49 | 50 | const unsigned int ids4Pal[8]= 51 | { 52 | 0x00100000,0x02100200,0x40104000,0x63184200,0x001F4210,0x03FF03E0,0x7C1F7C00,0x7FFF7FE0, 53 | }; 54 | 55 | const unsigned int ids4Tiles[40]= 56 | { 57 | 0x00000000,0x00000000,0x00000E00,0x0000E0E0,0x0000E0E0,0x0000E0E0,0x00000E00,0x00000000, 58 | 0x00000000,0x00000000,0x09900E00,0x0900E0E0,0x0900E0E0,0x0900E0E0,0x99900E00,0x00000000, 59 | 0x00000000,0x00000000,0x09900E00,0x9000E0E0,0x0900E0E0,0x0090E0E0,0x99900E00,0x00000000, 60 | 0x00000000,0x00000000,0x09000EE0,0x90900E00,0x90900E00,0x90900E00,0x0900EEE0,0x00000000, 61 | 0x00000000,0x00000000,0x09900EE0,0x09000E00,0x09000E00,0x09000E00,0x9990EEE0,0x00000000, 62 | }; 63 | 64 | -------------------------------------------------------------------------------- /basic/cbb_demo/source/cbb_ids.h: -------------------------------------------------------------------------------- 1 | //====================================================================== 2 | // 3 | // ids8, 72x8@8, 4 | // + 9 tiles not compressed 5 | // Total size: 576 = 576 6 | // 7 | // Time-stamp: 2005-12-24, 18:28:50 8 | // Exported by Cearn's Usenti v1.7.1 9 | // (comments, kudos, flames to "daytshen@hotmail.com") 10 | // 11 | //====================================================================== 12 | 13 | #ifndef __IDS8__ 14 | #define __IDS8__ 15 | 16 | #define ids8TilesLen 576 17 | extern const unsigned int ids8Tiles[144]; 18 | 19 | #endif // __IDS8__ 20 | 21 | //====================================================================== 22 | // 23 | // ids4, 40x8@4, 24 | // + palette 16 entries, not compressed 25 | // + 5 tiles not compressed 26 | // Total size: 32 + 160 = 192 27 | // 28 | // Time-stamp: 2005-12-24, 18:29:29 29 | // Exported by Cearn's Usenti v1.7.1 30 | // (comments, kudos, flames to "daytshen@hotmail.com") 31 | // 32 | //====================================================================== 33 | 34 | #ifndef __IDS4__ 35 | #define __IDS4__ 36 | 37 | #define ids4PalLen 32 38 | extern const unsigned int ids4Pal[8]; 39 | 40 | #define ids4TilesLen 160 41 | extern const unsigned int ids4Tiles[40]; 42 | 43 | #endif // __IDS4__ 44 | 45 | -------------------------------------------------------------------------------- /basic/first/source/first.c: -------------------------------------------------------------------------------- 1 | // 2 | // first.c 3 | // "Hello World" equivalent 4 | // 5 | // (20030901 - 20060211, cearn) 6 | // === NOTES === 7 | // * You are not expected to understand this. Check second.c for 8 | // a more proper version. 9 | 10 | 11 | int main() 12 | { 13 | *(unsigned int*)0x04000000= 0x0403; 14 | 15 | ((unsigned short*)0x06000000)[120+80*240]= 0x001F; 16 | ((unsigned short*)0x06000000)[136+80*240]= 0x03E0; 17 | ((unsigned short*)0x06000000)[120+96*240]= 0x7C00; 18 | 19 | while(1); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /basic/hello/source/hello.c: -------------------------------------------------------------------------------- 1 | // 2 | //! \file hello_demo.c 3 | //! Screen-entry text demo 4 | //! \date 20060228 - 20080416 5 | //! \author cearn 6 | // 7 | // === NOTES === 8 | 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 15 | 16 | // Init BG 0 for text on screen entries. 17 | tte_init_se_default(0, BG_CBB(0)|BG_SBB(31)); 18 | 19 | tte_write("#{P:72,64}"); // Goto (72, 64). 20 | tte_write("Hello World!"); // Print "Hello world!" 21 | 22 | while(1); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /basic/key_demo/graphics/gba_pic.grit: -------------------------------------------------------------------------------- 1 | # 2 | # GBA : bitmap, 8bpp, flat-layout, not compressed. 3 | # 4 | -gb -gB8 -m -mLf 5 | -------------------------------------------------------------------------------- /basic/key_demo/graphics/gba_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/key_demo/graphics/gba_pic.png -------------------------------------------------------------------------------- /basic/key_demo/source/key_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // key_demo.c 3 | // 4 | // demonstating key states (and minor palette animation) 5 | // 6 | // (20030927 - 20060922, cearn) 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "gba_pic.h" 13 | 14 | #define BTN_PAL 5 15 | #define CLR_UP RGB15(27,27,29) 16 | 17 | 18 | int main() 19 | { 20 | int ii; 21 | u32 btn; 22 | COLOR clr; 23 | int frame=0; 24 | 25 | memcpy32(vid_mem, gba_picBitmap, gba_picBitmapLen / sizeof(u32)); 26 | memcpy16(pal_bg_mem, gba_picPal, gba_picPalLen / sizeof(u16)); 27 | 28 | REG_DISPCNT= DCNT_MODE4 | DCNT_BG2; 29 | 30 | while(1) 31 | { 32 | vid_vsync(); 33 | // slowing down polling to make the changes visible 34 | if((frame & 7) == 0) 35 | key_poll(); 36 | // check state of each button 37 | for(ii=0; ii 8 | 9 | int main() 10 | { 11 | int ii, jj; 12 | 13 | REG_DISPCNT= DCNT_MODE3 | DCNT_BG2; 14 | 15 | // Fill screen with gray color 16 | m3_fill(RGB15(12, 12, 14)); 17 | 18 | // Rectangles: 19 | m3_rect( 12, 8, 108, 72, CLR_RED); 20 | m3_rect(108, 72, 132, 88, CLR_LIME); 21 | m3_rect(132, 88, 228, 152, CLR_BLUE); 22 | 23 | // Rectangle frames 24 | m3_frame(132, 8, 228, 72, CLR_CYAN); 25 | m3_frame(109, 73, 131, 87, CLR_BLACK); 26 | m3_frame( 12, 88, 108, 152, CLR_YELLOW); 27 | 28 | // Lines in top right frame 29 | for(ii=0; ii<=8; ii++) 30 | { 31 | jj= 3*ii+7; 32 | m3_line(132+11*ii, 9, 226, 12+7*ii, RGB15(jj, 0, jj)); 33 | m3_line(226-11*ii,70, 133, 69-7*ii, RGB15(jj, 0, jj)); 34 | } 35 | 36 | // Lines in bottom left frame 37 | for(ii=0; ii<=8; ii++) 38 | { 39 | jj= 3*ii+7; 40 | m3_line(15+11*ii, 88, 104-11*ii, 150, RGB15(0, jj, jj)); 41 | } 42 | 43 | while(1); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /basic/obj_demo/graphics/metr.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Metroid : 4bpp, not compressed. Only use the first 64 columns. 3 | # 4 | -gB4 -ar64 5 | -------------------------------------------------------------------------------- /basic/obj_demo/graphics/metr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/obj_demo/graphics/metr.png -------------------------------------------------------------------------------- /basic/obj_demo/source/obj_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // obj_demo.c 3 | // testing various sprite related things 4 | // 5 | // (20031003 - 20060924, Cearn) 6 | 7 | #include 8 | #include 9 | #include "metr.h" 10 | 11 | OBJ_ATTR obj_buffer[128]; 12 | OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer; 13 | 14 | // testing a few sprite things 15 | // D-pad: move 16 | // SELECT: switch palette 17 | // START: toggle mapping mode 18 | // A: horizontal flip 19 | // B: vertical flip 20 | // L & R shift starting tile 21 | void obj_test() 22 | { 23 | int x= 96, y= 32; 24 | u32 tid= 0, pb= 0; // tile id, pal-bank 25 | 26 | OBJ_ATTR *metr= &obj_buffer[0]; 27 | obj_set_attr(metr, 28 | ATTR0_SQUARE, // Square, regular sprite 29 | ATTR1_SIZE_64, // 64x64p, 30 | ATTR2_PALBANK(pb) | tid); // palbank 0, tile 0 31 | 32 | // position sprite (redundant here; the _real_ position 33 | // is set further down 34 | obj_set_pos(metr, x, y); 35 | 36 | while(1) 37 | { 38 | vid_vsync(); 39 | key_poll(); 40 | 41 | // move left/right 42 | x += 2*key_tri_horz(); 43 | 44 | // move up/down 45 | y += 2*key_tri_vert(); 46 | 47 | // increment/decrement starting tile with R/L 48 | tid += bit_tribool(key_hit(-1), KI_R, KI_L); 49 | 50 | // flip 51 | if(key_hit(KEY_A)) // horizontally 52 | metr->attr1 ^= ATTR1_HFLIP; 53 | if(key_hit(KEY_B)) // vertically 54 | metr->attr1 ^= ATTR1_VFLIP; 55 | 56 | // make it glow (via palette swapping) 57 | pb= key_is_down(KEY_SELECT) ? 1 : 0; 58 | 59 | // toggle mapping mode 60 | if(key_hit(KEY_START)) 61 | REG_DISPCNT ^= DCNT_OBJ_1D; 62 | 63 | // Hey look, it's one of them build macros! 64 | metr->attr2= ATTR2_BUILD(tid, pb, 0); 65 | obj_set_pos(metr, x, y); 66 | 67 | oam_copy(oam_mem, obj_buffer, 1); // only need to update one 68 | } 69 | } 70 | 71 | int main() 72 | { 73 | // Places the glyphs of a 4bpp boxed metroid sprite 74 | // into LOW obj memory (cbb == 4) 75 | memcpy32(&tile_mem[4][0], metrTiles, metrTilesLen / sizeof(u32)); 76 | memcpy16(pal_obj_mem, metrPal, metrPalLen / sizeof(u16)); 77 | 78 | oam_init(obj_buffer, 128); 79 | REG_DISPCNT= DCNT_OBJ | DCNT_OBJ_1D; 80 | 81 | obj_test(); 82 | 83 | while(1); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /basic/pageflip/graphics/page_pic.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Page pic : bitmap, 8bpp, flat-layout, not compressed. 3 | # 4 | -gb -gB8 -m -mLf 5 | -------------------------------------------------------------------------------- /basic/pageflip/graphics/page_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/basic/pageflip/graphics/page_pic.png -------------------------------------------------------------------------------- /basic/pageflip/source/pageflip.c: -------------------------------------------------------------------------------- 1 | // 2 | // pageflip.c 3 | // Shows mode4 page flipping 4 | // 5 | // (20031003 - 20060922, Cearn) 6 | // (20221114, AntonioND) 7 | 8 | #include 9 | 10 | #include 11 | #include "page_pic.h" 12 | 13 | void load_gfx() 14 | { 15 | const size_t bitmap_size = page_picBitmapLen / (2 * sizeof(unsigned int)); 16 | const unsigned int *frontBitmap = page_picBitmap; 17 | const unsigned int *backBitmap = frontBitmap + bitmap_size; 18 | 19 | int ii; 20 | for(ii=0; ii<16; ii++) 21 | { 22 | memcpy32(&vid_mem_front[ii*120], &frontBitmap[ii*144/4], 144/4); 23 | memcpy32(&vid_mem_back[ii*120], &backBitmap[ii*144/4], 144/4); 24 | } 25 | 26 | memcpy16(&pal_bg_mem[0], page_picPal, page_picPalLen/2); 27 | } 28 | 29 | int main() 30 | { 31 | load_gfx(); 32 | REG_DISPCNT= DCNT_MODE4 | DCNT_BG2; 33 | 34 | int ii=0; 35 | 36 | while(1) 37 | { 38 | while(KEY_DOWN_NOW(KEY_START)) ; // pause with start 39 | 40 | vid_vsync(); 41 | if(++ii == 60) 42 | { 43 | ii=0; 44 | vid_flip(); 45 | } 46 | } 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /basic/sbb_reg/source/sbb_reg.c: -------------------------------------------------------------------------------- 1 | // 2 | // map_block1.c 3 | // showing map-block boundaries regular backgrounds 4 | // 5 | // (20031114 - 20060317, Cearn) 6 | 7 | #include 8 | 9 | #define CBB_0 0 10 | #define SBB_0 28 11 | 12 | #define CROSS_TX 15 13 | #define CROSS_TY 10 14 | 15 | BG_POINT bg0_pt= { 0, 0 }; 16 | SCR_ENTRY *bg0_map= se_mem[SBB_0]; 17 | 18 | 19 | u32 se_index(u32 tx, u32 ty, u32 pitch) 20 | { 21 | u32 sbb= ((tx>>5)+(ty>>5)*(pitch>>5)); 22 | 23 | return sbb*1024 + ((tx&31)+(ty&31)*32); 24 | } 25 | 26 | void init_map() 27 | { 28 | int ii, jj; 29 | 30 | // initialize a background 31 | REG_BG0CNT= BG_CBB(CBB_0) | BG_SBB(SBB_0) | BG_REG_64x64; 32 | REG_BG0HOFS= 0; 33 | REG_BG0VOFS= 0; 34 | 35 | // create the tiles: basic tile and a cross 36 | const TILE tiles[2]= 37 | { 38 | {{0x11111111, 0x01111111, 0x01111111, 0x01111111, 39 | 0x01111111, 0x01111111, 0x01111111, 0x00000001}}, 40 | {{0x00000000, 0x00100100, 0x01100110, 0x00011000, 41 | 0x00011000, 0x01100110, 0x00100100, 0x00000000}}, 42 | }; 43 | tile_mem[CBB_0][0]= tiles[0]; 44 | tile_mem[CBB_0][1]= tiles[1]; 45 | 46 | // create a palette 47 | pal_bg_bank[0][1]= RGB15(31, 0, 0); 48 | pal_bg_bank[1][1]= RGB15( 0, 31, 0); 49 | pal_bg_bank[2][1]= RGB15( 0, 0, 31); 50 | pal_bg_bank[3][1]= RGB15(16, 16, 16); 51 | 52 | // Create a map: four contingent blocks of 53 | // 0x0000, 0x1000, 0x2000, 0x3000. 54 | SCR_ENTRY *pse= bg0_map; 55 | for(ii=0; ii<4; ii++) 56 | for(jj=0; jj<32*32; jj++) 57 | *pse++= SE_PALBANK(ii) | 0; 58 | } 59 | 60 | int main() 61 | { 62 | init_map(); 63 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0 | DCNT_OBJ; 64 | 65 | u32 tx, ty, se_curr, se_prev= CROSS_TY*32+CROSS_TX; 66 | 67 | bg0_map[se_prev]++; // initial position of cross 68 | while(1) 69 | { 70 | vid_vsync(); 71 | 72 | key_poll(); 73 | bg0_pt.x += key_tri_horz(); 74 | bg0_pt.y += key_tri_vert(); 75 | 76 | // Testing bg_se_id() 77 | // If all goes well the cross should be around the center of 78 | // the screen at all times. 79 | tx= ((bg0_pt.x>>3)+CROSS_TX) & 0x3F; 80 | ty= ((bg0_pt.y>>3)+CROSS_TY) & 0x3F; 81 | 82 | se_curr= se_index(tx, ty, 64); 83 | if(se_curr != se_prev) 84 | { 85 | bg0_map[se_prev]--; 86 | bg0_map[se_curr]++; 87 | se_prev= se_curr; 88 | } 89 | 90 | REG_BG_OFS[0]= bg0_pt; // write new position 91 | } 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /basic/second/source/second.c: -------------------------------------------------------------------------------- 1 | // 2 | // second.c 3 | // Cleaner version of 'first.c' 4 | // 5 | // (20060211 - 20060922, cearn) 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | REG_DISPCNT= DCNT_MODE3 | DCNT_BG2; 12 | 13 | m3_plot( 120, 80, RGB15(31, 0, 0) ); // or CLR_RED 14 | m3_plot( 136, 80, RGB15( 0,31, 0) ); // or CLR_LIME 15 | m3_plot( 120, 96, RGB15( 0, 0,31) ); // or CLR_BLUE 16 | 17 | while(1); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ext/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS:= `ls` 2 | 3 | all: 4 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i || { exit 1;} fi; done; 5 | clean: 6 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i clean || { exit 1;} fi; done; 7 | -------------------------------------------------------------------------------- /ext/bld_demo/graphics/metr.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Metroid : 4bpp, not compressed. Only use the first 64 columns. 3 | # 4 | -gB4 -ar64 5 | -------------------------------------------------------------------------------- /ext/bld_demo/graphics/metr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/bld_demo/graphics/metr.png -------------------------------------------------------------------------------- /ext/bld_demo/source/bld_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // bld_demo.c 3 | // testing blending 4 | // 5 | // (20031013 - 20060926, cearn) 6 | // bg 0, cbb 0, sbb 31, pb 15: text 7 | // bg 1, cbb 2, sbb 30, pb 1: metroid 8 | // bg 2, cbb 2, sbb 29, pb 0: fence 9 | // oam 0: tile 0-63: obj metroid 10 | 11 | #include 12 | #include 13 | #include "metr.h" 14 | 15 | void test_blend() 16 | { 17 | tte_printf("#{P:48,8}obj#{P:168,8}bg"); 18 | tte_set_margins(16, SCR_H-4-4*12, SCR_W-4, SCR_H-4); 19 | 20 | int mode=0; 21 | // eva, evb and ey are .4 fixeds 22 | // eva is full, evb and ey are empty 23 | u32 eva=0x80, evb= 0, ey=0; 24 | 25 | REG_BLDCNT= BLD_BUILD( 26 | BLD_OBJ | BLD_BG1, // Top 27 | BLD_BG2, // Bottom 28 | mode); // Mode 29 | // also try this variation sometime: 30 | // REG_BLDCNT= BLD_BUILD(BLD_OBJ | BLD_BG1 |BLD_BG2, BLD_BG2 | BLD_BD, mode); 31 | 32 | while(1) 33 | { 34 | vid_vsync(); 35 | key_poll(); 36 | 37 | // interactive blend weights 38 | eva += key_tri_horz(); 39 | evb -= key_tri_vert(); 40 | ey += key_tri_fire(); 41 | 42 | mode += bit_tribool(key_hit(-1), KI_R, KI_L); 43 | 44 | // clamp to allowable ranges 45 | eva = clamp(eva, 0, 0x81); 46 | evb = clamp(evb, 0, 0x81); 47 | ey = clamp(ey , 0, 0x81); 48 | mode= clamp(mode, 0, 4); 49 | 50 | tte_printf("#{es;P}mode :\t%2d\neva :\t%2d\nevb :\t%2d\ney :\t%2d", 51 | mode, eva/8, evb/8, ey/8); 52 | 53 | // Update blend mode 54 | BFN_SET(REG_BLDCNT, mode, BLD_MODE); 55 | 56 | // Update blend weights 57 | REG_BLDALPHA= BLDA_BUILD(eva/8, evb/8); 58 | REG_BLDY= BLDY_BUILD(ey/8); 59 | } 60 | } 61 | 62 | void load_metr() 63 | { 64 | // copy sprite and bg tiles, and the sprite palette 65 | memcpy32(&tile_mem[2][0], metrTiles, metrTilesLen/4); 66 | memcpy32(&tile_mem[4][0], metrTiles, metrTilesLen/4); 67 | memcpy32(pal_obj_mem, metrPal, metrPalLen/4); 68 | 69 | // Set the metroid sprite 70 | obj_set_attr(&oam_mem[0], ATTR0_SQUARE | ATTR0_BLEND | ATTR0_Y(24), 71 | ATTR1_SIZE_64 | ATTR1_X(32), 0); 72 | 73 | // Create the metroid bg using inverted palette for bg-metroid 74 | int ix, iy; 75 | for(ix=0; ix<16; ix++) 76 | pal_bg_mem[ix+16]= pal_obj_mem[ix] ^ CLR_WHITE; 77 | 78 | SCR_ENTRY *pse= &se_mem[30][3*32+18]; // right-center 79 | for(iy=0; iy<8; iy++) 80 | for(ix=0; ix<8; ix++) 81 | pse[iy*32+ix]= iy*8+ix + SE_PALBANK(1); 82 | 83 | REG_BG1CNT= BG_CBB(2) | BG_SBB(30); 84 | } 85 | 86 | // set-up the fence/text background 87 | void load_fence() 88 | { 89 | // tile 0 / ' ' will be a fence tile 90 | const TILE fence= 91 | {{ 92 | 0x00012000, 0x00012000, 0x00022200, 0x22220222, 93 | 0x11122211, 0x00112000, 0x00012000, 0x00012000, 94 | }}; 95 | tile_mem[2][64]= fence; 96 | 97 | se_fill(se_mem[29], 64); 98 | 99 | pal_bg_mem[0]= RGB15(16, 10, 20); 100 | pal_bg_mem[1]= RGB15( 0, 0, 31); 101 | pal_bg_mem[2]= RGB15(16, 16, 16); 102 | 103 | REG_BG2CNT= BG_CBB(2) | BG_SBB(29); 104 | } 105 | 106 | int main() 107 | { 108 | oam_init(oam_mem, 128); 109 | load_metr(); 110 | load_fence(); 111 | 112 | tte_init_chr4c_b4_default(0, BG_CBB(0)|BG_SBB(31)); 113 | tte_init_con(); 114 | 115 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | 116 | DCNT_OBJ | DCNT_OBJ_1D; 117 | 118 | test_blend(); 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /ext/dma_demo/graphics/brin.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Brinstar : 64x64t, 4bpp, SBB-layout, not compressed. 3 | # 4 | -gt -gB4 -mR4 -mLs 5 | -------------------------------------------------------------------------------- /ext/dma_demo/graphics/brin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/dma_demo/graphics/brin.png -------------------------------------------------------------------------------- /ext/dma_demo/source/dma_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // dma_demo.c 3 | // Circular window via HDMA 4 | // 5 | // (20031210 - 20070808, Cearn) 6 | // === NOTES === 7 | 8 | #include 9 | #include 10 | 11 | #include "brin.h" 12 | 13 | u16 g_winh[SCREEN_HEIGHT+1]; 14 | 15 | //! Create an array of horizontal offsets for a circular window. 16 | /*! The offsets are to be copied to REG_WINxH each HBlank, either 17 | * by HDMA or HBlank isr. Offsets provided by modified 18 | * Bresenham's circle routine (of course); the clipping code is not 19 | * optional. 20 | * \param winh Pointer to array to receive the offsets. 21 | * \param x0 X-coord of circle center. 22 | * \param y0 Y-coord of circle center. 23 | * \param rr Circle radius. 24 | */ 25 | void win_circle(u16 winh[], int x0, int y0, int rr) 26 | { 27 | int x=0, y= rr, d= 1-rr; 28 | u32 tmp; 29 | 30 | // clear the whole array first. 31 | memset16(winh, 0, SCREEN_HEIGHT+1); 32 | 33 | while(y >= x) 34 | { 35 | // Side octs 36 | tmp = clamp(x0+y, 0, SCREEN_WIDTH+1); 37 | tmp += clamp(x0-y, 0, SCREEN_WIDTH+1)<<8; 38 | 39 | if(IN_RANGE(y0-x, 0, SCREEN_HEIGHT)) // o4, o7 40 | winh[y0-x]= tmp; 41 | if(IN_RANGE(y0+x, 0, SCREEN_HEIGHT)) // o0, o3 42 | winh[y0+x]= tmp; 43 | 44 | // Change in y: top/bottom octs 45 | if(d >= 0) 46 | { 47 | tmp = clamp(x0+x, 0, SCREEN_WIDTH+1); 48 | tmp += clamp(x0-x, 0, SCREEN_WIDTH+1)<<8; 49 | 50 | if(IN_RANGE(y0-y, 0, SCREEN_HEIGHT)) // o5, o6 51 | winh[y0-y]= tmp; 52 | if(IN_RANGE(y0+y, 0, SCREEN_HEIGHT)) // o1, o2 53 | winh[y0+y]= tmp; 54 | 55 | d -= 2*(--y); 56 | } 57 | d += 2*(x++)+3; 58 | } 59 | winh[SCREEN_HEIGHT]= winh[0]; 60 | } 61 | 62 | void init_main() 63 | { 64 | // --- Init BG 2 (main bg) --- 65 | dma3_cpy(pal_bg_mem, brinPal, brinPalLen); 66 | dma3_cpy(tile_mem[0], brinTiles, brinTilesLen); 67 | dma3_cpy(se_mem[30], brinMap, brinMapLen); 68 | 69 | //memcpy32(pal_bg_mem, brinPal, brinPalLen/4); 70 | //memcpy32(tile_mem[0], brinTiles, brinTilesLen/4); 71 | //memcpy32(se_mem[30], brinMap, brinMapLen/4); 72 | 73 | REG_BG2CNT= BG_CBB(0)|BG_SBB(30) | BG_REG_64x32; 74 | REG_BG2HOFS= 120; 75 | REG_BG2VOFS= 64; 76 | 77 | // --- Init BG 1 (mask) --- 78 | const TILE tile= 79 | {{ 80 | 0xF2F3F2F3, 0x3F2F3F2F, 0xF3F2F3F2, 0x2F3F2F3F, 81 | 0xF2F3F2F3, 0x3F2F3F2F, 0xF3F2F3F2, 0x2F3F2F3F 82 | }}; 83 | tile_mem[0][32]= tile; 84 | pal_bg_bank[4][ 2]= RGB15(12,12,12); 85 | pal_bg_bank[4][ 3]= RGB15( 8, 8, 8); 86 | pal_bg_bank[4][15]= RGB15( 0, 0, 0); 87 | se_fill(se_mem[29], 0x4020); 88 | 89 | REG_BG1CNT= BG_CBB(0)|BG_SBB(29); 90 | 91 | // --- Init BG 0 (text) --- 92 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 93 | tte_init_con(); 94 | tte_set_margins(8, 8, 232, 40); 95 | 96 | // --- Init window --- 97 | REG_WIN0H= 0; 98 | REG_WIN0V= SCREEN_HEIGHT; 99 | 100 | // --- Enable stuff --- 101 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_WIN0; 102 | REG_WININ= WIN_BUILD(WIN_BG0|WIN_BG2, 0); 103 | REG_WINOUT= WIN_BUILD(WIN_BG0|WIN_BG1, 0); 104 | } 105 | 106 | int main() 107 | { 108 | int rr=64, x0=120, y0=80; 109 | 110 | init_main(); 111 | 112 | while(1) 113 | { 114 | vid_vsync(); 115 | key_poll(); 116 | 117 | rr += key_tri_shoulder(); // size with B/A 118 | x0 += key_tri_horz(); // move left/right 119 | y0 += key_tri_vert(); // move up/down 120 | 121 | if(rr<0) 122 | rr= 0; 123 | 124 | // Fill circle array 125 | win_circle(g_winh, x0, y0, rr); 126 | 127 | // Init win-circle HDMA 128 | DMA_TRANSFER(®_WIN0H, &g_winh[1], 1, 3, DMA_HDMA); 129 | 130 | tte_printf("#{es;P}%d %d | %d ", x0, y0, rr); 131 | } 132 | 133 | return 0; 134 | } 135 | 136 | -------------------------------------------------------------------------------- /ext/irq_demo/source/irq_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // irq_demo.c 3 | // Interrupts: routed, nested and prioritized 4 | // 5 | // (20061022 - 20080404, Cearn) 6 | // === NOTES === 7 | 8 | 9 | #include 10 | #include 11 | 12 | IWRAM_CODE void isr_master(); 13 | IWRAM_CODE void hbl_grad_direct(); 14 | 15 | void vct_wait(); 16 | void vct_wait_nest(); 17 | 18 | 19 | CSTR strings[]= 20 | { 21 | "asm/nested", "c/direct", 22 | "VCount", "HBlank" 23 | }; 24 | 25 | // Function pointers to master isrs. 26 | const fnptr master_isrs[2]= 27 | { 28 | (fnptr)isr_master, 29 | (fnptr)hbl_grad_direct 30 | }; 31 | 32 | // VCount interrupt routines. 33 | const fnptr vct_isrs[2]= 34 | { 35 | vct_wait, 36 | vct_wait_nest 37 | }; 38 | 39 | 40 | // (1) Uses tonc_isr_master.s' isr_master() as a switchboard 41 | void hbl_grad_routed() 42 | { 43 | u32 clr= REG_VCOUNT/8; 44 | pal_bg_mem[0]= RGB15(clr, 0, 31-clr); 45 | } 46 | 47 | // (2) VCT is triggered at line 80; this waits 40 scanlines 48 | void vct_wait() 49 | { 50 | pal_bg_mem[0]= CLR_RED; 51 | while(REG_VCOUNT<120); 52 | } 53 | 54 | // As vct_wait(), but interruptable by HBlank 55 | void vct_wait_nest() 56 | { 57 | pal_bg_mem[0]= CLR_RED; 58 | REG_IE= IRQ_HBLANK; // Allow nested hblanks 59 | REG_IME= 1; 60 | while(REG_VCOUNT<120); 61 | } 62 | 63 | 64 | int main() 65 | { 66 | u32 bDirect=0, bVctPrio= 0; 67 | 68 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 69 | tte_set_drawg((fnDrawg)chr4c_drawg_b4cts_fast); 70 | tte_init_con(); 71 | tte_set_margins(8, 8, 128, 64); 72 | 73 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 74 | 75 | // (3) Initialise irqs; add HBL and VCT isrs 76 | // and set VCT to trigger at 80 77 | irq_init(master_isrs[0]); 78 | irq_add(II_HBLANK, hbl_grad_routed); 79 | BFN_SET(REG_DISPSTAT, 80, DSTAT_VCT); 80 | irq_add(II_VCOUNT, vct_wait); 81 | 82 | irq_add(II_VBLANK, NULL); 83 | 84 | while(1) 85 | { 86 | //vid_vsync(); 87 | VBlankIntrWait(); 88 | key_poll(); 89 | 90 | // Toggle HBlank irq 91 | if(key_hit(KEY_R)) 92 | REG_IE ^= IRQ_HBLANK; 93 | 94 | // Toggle Vcount irq 95 | if(key_hit(KEY_L)) 96 | REG_IE ^= IRQ_VCOUNT; 97 | 98 | // (4) Toggle between 99 | // asm switchblock + hbl_gradient (red, descending) 100 | // or purely hbl_isr_in_c (green, ascending) 101 | if(key_hit(KEY_A)) 102 | { 103 | bDirect ^= 1; 104 | irq_set_master(master_isrs[bDirect]); 105 | } 106 | 107 | // (5) Switch priorities of HBlank and VCount 108 | if(key_hit(KEY_B)) 109 | { 110 | //irq_set(II_VCOUNT, vct_wait, bVctPrio); 111 | bVctPrio ^= 1; 112 | irq_add(II_VCOUNT, vct_isrs[bVctPrio]); 113 | } 114 | 115 | tte_printf("#{es;P}ISR#{X:32}: %s\nPrio#{X:32}: %s\nIE#{X:32}: %04X", 116 | strings[bDirect], strings[2+bVctPrio], REG_IE); 117 | } 118 | 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /ext/irq_demo/source/isr.iwram.c: -------------------------------------------------------------------------------- 1 | // 2 | // isr.iwram.c 3 | // 4 | // (20050607 - 20050615, Cearn) 5 | // === NOTES === 6 | // * An *.iwram.c is automatically put in IWRAM (in DKP at least) 7 | // Create an extra rule to compile as ARM code 8 | 9 | #include 10 | 11 | IWRAM_CODE void hbl_grad_direct(); 12 | 13 | // an interrupt routine purely in C 14 | // (make SURE you compile in ARM mode!!) 15 | void hbl_grad_direct() 16 | { 17 | u32 irqs= REG_IF & REG_IE; 18 | 19 | REG_IFBIOS |= irqs; 20 | 21 | if(irqs & IRQ_HBLANK) 22 | { 23 | u32 clr= REG_VCOUNT/8; 24 | pal_bg_mem[0]= RGB15(0, clr, 0); 25 | } 26 | 27 | REG_IF= irqs; 28 | } 29 | 30 | 31 | #define CPU_MODE_USER (0x10<< 0) 32 | #define CPU_MODE_FIQ (0x11<< 0) 33 | #define CPU_MODE_IRQ (0x12<< 0) 34 | #define CPU_MODE_SVC (0x13<< 0) 35 | #define CPU_MODE_ABT (0x17<< 0) 36 | #define CPU_MODE_UND (0x1B<< 0) 37 | #define CPU_MODE_SYS (0x1F<< 0) 38 | 39 | #define CPU_THUMB (1<< 5) 40 | #define CPU_FIQ_OFF (1<< 6) 41 | #define CPU_IRQ_OFF (1<< 7) 42 | 43 | #define CPU_MODE_MASK (0x1F<< 0) 44 | 45 | 46 | // This is mostly what tonclib's isr_master_nest does, but 47 | // you really need asm for the full functionality 48 | IWRAM_CODE void isr_master_nest_c() 49 | { 50 | u32 ie= REG_IE, ieif= ie ®_IF, irq_prio= 0; 51 | IRQ_REC *pir; 52 | 53 | REG_IFBIOS= ieif; // Ack for BIOS routines 54 | 55 | // --- Find raised irq --- 56 | for(pir= __isr_table; pir->flag; pir++) 57 | { 58 | if(pir->flag & ieif) 59 | break; 60 | irq_prio |= pir->flag; 61 | } 62 | // Irq not recognized or has no isr: 63 | // Just ack in REG_IF and return 64 | if(pir->flag == 0 || pir->isr == NULL) 65 | { 66 | REG_IF= ieif; 67 | return; 68 | } 69 | 70 | REG_IME= 0; 71 | 72 | // --- CPU back to system mode --- 73 | //> *--sp_irq= lr_irq; 74 | //> cpsr &= ~(CPU_MODE_MASK | CPU_IRQ_OFF); 75 | //> cpsr |= CPU_MODE_SYS; 76 | //> *--sp_sys = lr_sys; 77 | 78 | REG_IE= irq_prio; // Allow only irqs of higher priority 79 | REG_IME= 1; 80 | 81 | pir->isr(); 82 | 83 | u32 ime= REG_IME; 84 | REG_IME= 0; 85 | 86 | // --- Back to irq mode --- 87 | //> lr_sys = *sp_sys++; 88 | //> cpsr &= ~(CPU_MODE_MASK | CPU_IRQ_OFF); 89 | //> cpsr |= CPU_MODE_IRQ | CPU_IRQ_OFF; 90 | //> lr_irq = *sp_irq++; 91 | 92 | // Restore ie and ack handled irq 93 | REG_IE= ie; 94 | REG_IF= pir->flag<<16; 95 | REG_IME= ime; 96 | } 97 | -------------------------------------------------------------------------------- /ext/mos_demo/graphics/metr.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Metroid : 4bpp, not compressed. Only use the first 64 columns. 3 | # 4 | -gB4 -ar64 5 | -------------------------------------------------------------------------------- /ext/mos_demo/graphics/metr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/mos_demo/graphics/metr.png -------------------------------------------------------------------------------- /ext/mos_demo/source/mos_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // mos_demo.c 3 | // testing a mosaic sprite and background 4 | // 5 | // (20031013 - 20071203, cearn) 6 | // === NOTES === 7 | // * bg/oam use: 8 | // bg 0, cbb 0, sbb 31, pb 0: text 9 | // bg 1, cbb 1, sbb 30, pb 1: bg metroid 10 | // oam 0: tile 0-63: obj metroid 11 | 12 | #include 13 | #include 14 | #include "metr.h" 15 | 16 | void test_mosaic() 17 | { 18 | tte_printf("#{P:48,8}obj#{P:168,8}bg"); 19 | tte_set_margins(4, SCR_H-30, SCR_W-4, SCR_H-4); 20 | 21 | POINT pt_obj={0,0}, pt_bg={0,0}; 22 | POINT *ppt= &pt_obj; 23 | 24 | while(1) 25 | { 26 | vid_vsync(); 27 | 28 | // control the mosaic 29 | key_poll(); 30 | 31 | // switch between bg or obj mosaic 32 | ppt= key_is_down(KEY_A) ? &pt_bg : &pt_obj; 33 | 34 | ppt->x += key_tri_horz(); // inc/dec h-mosaic 35 | ppt->y -= key_tri_vert(); // inc/dec v-mosaic 36 | 37 | ppt->x= clamp(ppt->x, 0, 0x80); 38 | ppt->y= clamp(ppt->y, 0, 0x80); 39 | 40 | REG_MOSAIC= MOS_BUILD(pt_bg.x>>3, pt_bg.y>>3, 41 | pt_obj.x>>3, pt_obj.y>>3); 42 | 43 | tte_printf("#{es;P}obj h,v: %2d,%2d\n bg h,v: %2d,%2d", 44 | pt_obj.x>>3, pt_obj.y>>3, pt_bg.x>>3, pt_bg.y>>3); 45 | } 46 | } 47 | 48 | void load_metr() 49 | { 50 | int ix, iy; 51 | 52 | memcpy32(&tile_mem[1][0], metrTiles, metrTilesLen/4); 53 | memcpy32(&tile_mem[4][0], metrTiles, metrTilesLen/4); 54 | memcpy32(pal_obj_mem, metrPal, metrPalLen/4); 55 | 56 | // create object: oe0 57 | OBJ_ATTR *metr= &oam_mem[0]; 58 | obj_set_attr(metr, ATTR0_SQUARE | ATTR0_MOSAIC, ATTR1_SIZE_64, 0); 59 | obj_set_pos(metr, 32, 24); // left-center 60 | 61 | // create bg map: bg1, cbb1, sbb 31 62 | for(ix=1; ix<16; ix++) 63 | pal_bg_mem[ix+16]= pal_obj_mem[ix] ^ CLR_WHITE; 64 | 65 | SCR_ENTRY *pse= &se_mem[30][3*32+18]; // right-center 66 | for(iy=0; iy<8; iy++) 67 | for(ix=0; ix<8; ix++) 68 | pse[iy*32+ix]= (iy*8+ix) | SE_PALBANK(1); 69 | 70 | REG_BG1CNT= BG_CBB(1) | BG_SBB(30) | BG_MOSAIC; 71 | } 72 | 73 | int main() 74 | { 75 | // setup sprite 76 | oam_init(oam_mem, 128); 77 | 78 | load_metr(); 79 | 80 | // set-up text: bg0, cbb0, sbb31 81 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(31)); 82 | tte_init_con(); 83 | 84 | REG_DISPCNT= DCNT_BG0 | DCNT_BG1 | DCNT_OBJ | DCNT_OBJ_1D; 85 | 86 | test_mosaic(); 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /ext/oacombo/graphics/oac_gfx.grit: -------------------------------------------------------------------------------- 1 | # 2 | # OAC GFX : 4bpp, not compressed. Use metatiles of 4x4 tiles. 3 | # 4 | -gB4 -Mh4 -Mw4 5 | -------------------------------------------------------------------------------- /ext/oacombo/graphics/oac_gfx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/oacombo/graphics/oac_gfx.png -------------------------------------------------------------------------------- /ext/oacombo/source/oacombo.c: -------------------------------------------------------------------------------- 1 | // 2 | // oacombo.c 3 | // Affine object combo's, with the off-center rotations 4 | // that go with it. 5 | // 6 | // (20060419 - 20070808, cearn) 7 | 8 | #include 9 | #include 10 | 11 | #include "oac_gfx.h" 12 | 13 | #define AX (16<<8) // X-anchor 14 | #define AY (16<<8) // Y-anchor 15 | #define X0 120 // base X 16 | #define Y0 36 // base Y 17 | 18 | void obj_rs_ex2(OBJ_ATTR *obj, OBJ_AFFINE *oa, AFF_SRC_EX *asx); 19 | 20 | typedef struct OACOMBO 21 | { 22 | OBJ_ATTR *sub_obj; // obj pointer for sub-objects 23 | POINT *sub_pos; // Local sub-object coords (.8f) 24 | int sub_count; // Number of sub-objects 25 | POINT pos; // Global position (.8f) 26 | POINT anchor; // Local anchor (.8f) 27 | s16 sx, sy; 28 | u16 alpha; 29 | } OACOMBO; 30 | 31 | 32 | // === GLOBALS ======================================================== 33 | 34 | OBJ_ATTR obj_buffer[128]; 35 | OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer; 36 | 37 | 38 | // Obj templates 39 | const OBJ_ATTR obj_data[7]= 40 | { 41 | // obj[0] , oa[0]: 1 full 32x32p double-affine circle 42 | { 0x0300, 0x8200, 0x0000, 0x0000 }, 43 | // obj[1-2], oa[1]: 2 32x16p double-affine semi-circles 44 | { 0x4300, 0x8200, 0x0000, 0x0000 }, 45 | { 0x4300, 0x8200, 0x0008, 0x0000 }, 46 | // obj[3-7], oa[1]: 4 16x16p double-affine quarter-circles 47 | { 0x0300, 0x4400, 0x0010, 0x0000 }, 48 | { 0x0300, 0x4400, 0x0014, 0x0000 }, 49 | { 0x0300, 0x4400, 0x0018, 0x0000 }, 50 | { 0x0300, 0x4400, 0x001C, 0x0000 }, 51 | }; 52 | 53 | POINT sub_pos[7]= 54 | { 55 | {0,0}, 56 | {0,0},{0,AY}, 57 | {0,0},{AX,0}, {0,AY},{AX,AY}, 58 | }; 59 | 60 | OACOMBO oacs[3]= 61 | { 62 | // full 32x32p double-affine circle 63 | { &obj_buffer[0], &sub_pos[0], 1, 64 | {(X0-48)<<8, Y0<<8}, {AX, AY}, 256, 256, 0 }, 65 | // 2 32x16p double-affine semi-circles 66 | { &obj_buffer[1], &sub_pos[1], 2, 67 | {(X0+16)<<8, Y0<<8}, {AX, AY}, 256, 256, 0 }, 68 | // 4 16x16p double-affine quarter-circles 69 | { &obj_buffer[3], &sub_pos[3], 4, 70 | {(X0-16)<<8, (Y0+40)<<8}, {AX, AY}, 256, 256, 0 }, 71 | }; 72 | 73 | 74 | // === FUNCTIONS ====================================================== 75 | 76 | void oac_rotscale(OACOMBO *oac) 77 | { 78 | // --- create P --- 79 | int sx= oac->sx, sy= oac->sy; 80 | int sina= lu_sin(oac->alpha)>>4, cosa= lu_cos(oac->alpha)>>4; 81 | 82 | OBJ_AFFINE *oaff= 83 | &obj_aff_buffer[BFN_GET(oac->sub_obj->attr1, ATTR1_AFF_ID)]; 84 | oaff->pa= cosa*sx>>8; oaff->pb= -sina*sx>>8; 85 | oaff->pc= sina*sy>>8; oaff->pd= cosa*sy>>8; 86 | 87 | // sx = 1/sx, sy = 1/sy (.12f) 88 | sx= Div(1<<20, sx); 89 | if(sx != sy) 90 | sy= Div(1<<20, sy); 91 | else 92 | sy= sx; 93 | FIXED aa, ab, ac, ad; 94 | aa= sx*cosa>>12; ab= sy*sina>>12; // .8f 95 | ac= -sx*sina>>12; ad= sy*cosa>>12; // .8f 96 | 97 | int ii; 98 | OBJ_ATTR *obj= oac->sub_obj; 99 | POINT *pt= oac->sub_pos; 100 | for(ii=0; iisub_count; ii++) 101 | { 102 | int dx, dy; // all .8f 103 | sx= oam_sizes[obj->attr0>>14][obj->attr1>>14][0]<<7; 104 | sy= oam_sizes[obj->attr0>>14][obj->attr1>>14][1]<<7; 105 | 106 | dx= oac->pos.x+oac->anchor.x - sx; // .8f 107 | dy= oac->pos.y+oac->anchor.y - sy; // .8f 108 | 109 | if(obj->attr0&ATTR0_AFF_DBL_BIT) 110 | { dx -= sx; dy -= sy; } 111 | 112 | sx= oac->anchor.x - pt->x - sx; 113 | sy= oac->anchor.y - pt->y - sy; 114 | 115 | dx -= (aa*sx + ab*sy)>>8; // .8f 116 | dy -= (ac*sx + ad*sy)>>8; // .8f 117 | obj_set_pos(obj, dx>>8, dy>>8); 118 | 119 | obj++; pt++; 120 | } 121 | } 122 | 123 | void init_main() 124 | { 125 | memcpy32(pal_obj_mem, oac_gfxPal, oac_gfxPalLen/4); 126 | memcpy32(tile_mem[4], oac_gfxTiles, oac_gfxTilesLen/4); 127 | 128 | oam_init(obj_buffer, 128); 129 | 130 | // init objs and obj combos 131 | memcpy32(obj_buffer, obj_data, sizeof(obj_data)/4); 132 | 133 | REG_DISPCNT= DCNT_BG0 | DCNT_OBJ | DCNT_OBJ_1D; 134 | 135 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 136 | tte_init_con(); 137 | 138 | // Some labels 139 | tte_printf("#{P:%d,%d}1 full #{P:%d,%d}2 semi #{P:%d,%d}4 quarts", 140 | X0-48, Y0-16, X0+20, Y0-16, X0-20, Y0+74); 141 | } 142 | 143 | 144 | int main() 145 | { 146 | init_main(); 147 | 148 | int ii, alpha=0; 149 | 150 | while(1) 151 | { 152 | vid_vsync(); 153 | key_poll(); 154 | alpha -= 128*key_tri_shoulder(); 155 | 156 | for(ii=0; ii<3; ii++) 157 | { 158 | oacs[ii].alpha= alpha; 159 | oac_rotscale(&oacs[ii]); 160 | } 161 | oam_copy(oam_mem, obj_buffer, 128); 162 | } 163 | return 0; 164 | } 165 | 166 | 167 | // alternate main; uses obj_rs_ex() 168 | int alt_main() 169 | { 170 | init_main(); 171 | 172 | AFF_SRC_EX asxs[7]= 173 | { 174 | // 1 32x32p double-affine circle 175 | { 16<<8, 16<<8, 32, 36, 256, 256, 0 }, 176 | // 2 32x16p double-affine semi-circles 177 | { 16<<8, 16<<8, 96, 36, 256, 256, 0 }, 178 | { 16<<8, 0 , 96, 36, 256, 256, 0 }, 179 | // 4 16x16p double-affine quarter-circles 180 | { 16<<8, 16<<8, 64, 76, 256, 256, 0 }, 181 | { 0 , 16<<8, 64, 76, 256, 256, 0 }, 182 | { 16<<8, 0 , 64, 76, 256, 256, 0 }, 183 | { 0 , 0 , 64, 76, 256, 256, 0 }, 184 | }; 185 | 186 | int ii, alpha=0; 187 | 188 | while(1) 189 | { 190 | vid_vsync(); 191 | key_poll(); 192 | alpha -= 128*key_tri_shoulder(); 193 | 194 | for(ii=0; ii<7; ii++) 195 | { 196 | asxs[ii].alpha= alpha; 197 | obj_rs_ex2(&obj_buffer[ii], &obj_aff_buffer[ii], &asxs[ii]); 198 | } 199 | 200 | oam_copy(oam_mem, obj_buffer, 128); 201 | } 202 | 203 | return 0; 204 | } 205 | 206 | -------------------------------------------------------------------------------- /ext/obj_aff/graphics/metr.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Metroid : 4bpp, not compressed. Only use the last 64 columns. 3 | # 4 | -gB4 -al64 5 | -------------------------------------------------------------------------------- /ext/obj_aff/graphics/metr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/obj_aff/graphics/metr.png -------------------------------------------------------------------------------- /ext/obj_aff/source/obj_aff.c: -------------------------------------------------------------------------------- 1 | // 2 | // obj_aff.c 3 | // Fun with affine transformations 4 | // 5 | // Note that the code is quite complex due to all the 6 | // different things you can do. 7 | // 8 | // (20031010 - 20070808, cearn) 9 | 10 | #include 11 | #include 12 | 13 | #include "metr.h" 14 | 15 | OBJ_ATTR obj_buffer[128]; 16 | OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer; 17 | 18 | 19 | // affine transformation constants and variables 20 | enum eAffState 21 | { 22 | AFF_NULL=0, AFF_ROTATE, AFF_SCALE_X, AFF_SCALE_Y, 23 | AFF_SHEAR_X, AFF_SHEAR_Y, AFF_COUNT 24 | }; 25 | 26 | // 'speeds' of transformations 27 | const int aff_diffs[AFF_COUNT]= { 0, 128, 4, 4, 4, 4 }; 28 | 29 | // keys for transformation direction 30 | const int aff_keys[AFF_COUNT]= 31 | { 0, KEY_L, KEY_SELECT, KEY_SELECT, KEY_RIGHT, KEY_UP }; 32 | int aff_state= AFF_NULL; 33 | int aff_value= 0; 34 | 35 | // === FUNCTIONS ====================================================== 36 | 37 | void init_metr() 38 | { 39 | // Places the tiles of a 4bpp metroid sprite into LOW obj VRAM 40 | memcpy32(tile_mem[4], metrTiles, metrTilesLen/4); 41 | memcpy32(pal_obj_mem, metrPal, metrPalLen/4); 42 | 43 | // setup main metroid 44 | obj_set_attr(obj_buffer, 45 | ATTR0_SQUARE | ATTR0_AFF, // Square Aff-sprite 46 | ATTR1_SIZE_64 | ATTR1_AFF_ID(0), // 64x64, using obj_aff[0] 47 | 0 | 0); // palbank 0, tile 0 48 | obj_set_pos(obj_buffer, 96, 32); 49 | obj_aff_identity(&obj_aff_buffer[0]); 50 | 51 | // setup shadow metroid 52 | obj_set_attr(&obj_buffer[1], 53 | ATTR0_SQUARE | ATTR0_AFF, // Square Aff-sprite 54 | ATTR1_SIZE_64 | ATTR1_AFF_ID(31), // 64x64, using obj_aff[0] 55 | ATTR2_PALBANK(1) | 0); // palbank 1, tile 0 56 | obj_set_pos(&obj_buffer[1], 96, 32); 57 | obj_aff_identity(&obj_aff_buffer[31]); 58 | 59 | oam_copy(oam_mem, obj_buffer, 128); 60 | } 61 | 62 | int get_aff_state() 63 | { 64 | if(key_is_down(KEY_L | KEY_R)) 65 | return AFF_ROTATE; 66 | if(key_is_down(KEY_A)) 67 | return AFF_SCALE_X; 68 | if(key_is_down(KEY_B)) 69 | return AFF_SCALE_Y; 70 | if(key_is_down(KEY_LEFT | KEY_RIGHT)) 71 | return AFF_SHEAR_X; 72 | if(key_is_down(KEY_UP | KEY_DOWN)) 73 | return AFF_SHEAR_Y; 74 | return AFF_NULL; 75 | } 76 | 77 | void get_aff_new(OBJ_AFFINE *oaff) 78 | { 79 | int diff= aff_diffs[aff_state]; 80 | aff_value += (key_is_down(aff_keys[aff_state]) ? diff : -diff); 81 | 82 | switch(aff_state) 83 | { 84 | case AFF_ROTATE: // L rotates left, R rotates right 85 | //aff_value &= SIN_MASK; 86 | obj_aff_rotate(oaff, aff_value); 87 | break; 88 | case AFF_SCALE_X: // A scales x, +SELECT scales down 89 | obj_aff_scale_inv(oaff, (1<<8)-aff_value, 1<<8); 90 | break; 91 | case AFF_SCALE_Y: // B scales y, +SELECT scales down 92 | obj_aff_scale_inv(oaff, 1<<8, (1<<8)-aff_value); 93 | break; 94 | case AFF_SHEAR_X: // shear left and right 95 | obj_aff_shearx(oaff, aff_value); 96 | break; 97 | case AFF_SHEAR_Y: // shear up and down 98 | obj_aff_sheary(oaff, aff_value); 99 | break; 100 | default: // shouldn't happen 101 | obj_aff_identity(oaff); 102 | } 103 | } 104 | 105 | void objaff_test() 106 | { 107 | OBJ_ATTR *metr= &obj_buffer[0], *shadow= &obj_buffer[1]; 108 | OBJ_AFFINE *oaff_curr= &obj_aff_buffer[0]; 109 | OBJ_AFFINE *oaff_base= &obj_aff_buffer[1]; 110 | OBJ_AFFINE *oaff_new= &obj_aff_buffer[2]; 111 | 112 | int x=96, y=32; 113 | int new_state; 114 | 115 | // oaff_curr = oaff_base * oaff_new 116 | // oaff_base changes when the aff-state changes 117 | // oaff_new is updated when it doesn't 118 | obj_aff_identity(oaff_curr); 119 | obj_aff_identity(oaff_base); 120 | obj_aff_identity(oaff_new); 121 | 122 | while(1) 123 | { 124 | key_poll(); 125 | 126 | // move sprite around 127 | if( key_is_down(KEY_SELECT) && key_is_down(KEY_DIR) ) 128 | { 129 | // move 130 | x += 2*key_tri_horz(); 131 | y += 2*key_tri_vert(); 132 | 133 | obj_set_pos(metr, x, y); 134 | obj_set_pos(shadow, x, y); 135 | new_state= AFF_NULL; 136 | } 137 | else // or do an affine transformation 138 | new_state= get_aff_state(); 139 | 140 | if(new_state != AFF_NULL) // no change 141 | { 142 | if(new_state == aff_state) // increase current transformation 143 | { 144 | get_aff_new(oaff_new); 145 | obj_aff_copy(oaff_curr, oaff_base, 1); 146 | obj_aff_postmul(oaff_curr, oaff_new); 147 | } 148 | else // switch to different transformation type 149 | { 150 | obj_aff_copy(oaff_base, oaff_curr, 1); 151 | obj_aff_identity(oaff_new); 152 | aff_value= 0; 153 | } 154 | aff_state= new_state; 155 | } 156 | 157 | // START: toggles double-size flag 158 | // START+SELECT: resets obj_aff to identity 159 | if(key_hit(KEY_START)) 160 | { 161 | if(key_is_down(KEY_SELECT)) 162 | { 163 | obj_aff_identity(oaff_curr); 164 | obj_aff_identity(oaff_base); 165 | obj_aff_identity(oaff_new); 166 | aff_value= 0; 167 | } 168 | else 169 | { 170 | metr->attr0 ^= ATTR0_AFF_DBL_BIT; 171 | shadow->attr0 ^= ATTR0_AFF_DBL_BIT; 172 | } 173 | } 174 | 175 | vid_vsync(); 176 | 177 | // we only have one OBJ_ATTR, so update that 178 | obj_copy(obj_mem, obj_buffer, 2); 179 | 180 | // we have 3 OBJ_AFFINEs, update these separately 181 | obj_aff_copy(obj_aff_mem, obj_aff_buffer, 3); 182 | 183 | // Display the current matrix 184 | tte_printf("#{es;P:8,136}P = " 185 | "#{y:-7;Ps}| %04X\t%04X#{Pr;x:72}|" 186 | "#{Pr;y:12}| %04X\t%04X#{Pr;p:72,12}|", 187 | (u16)oaff_curr->pa, (u16)oaff_curr->pb, 188 | (u16)oaff_curr->pc, (u16)oaff_curr->pd); 189 | } 190 | } 191 | 192 | int main() 193 | { 194 | REG_DISPCNT= DCNT_BG0 | DCNT_OBJ | DCNT_OBJ_1D; 195 | oam_init(obj_buffer, 128); 196 | init_metr(); 197 | 198 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 199 | tte_init_con(); 200 | tte_set_margins(8, 128, 232, 160); 201 | 202 | objaff_test(); 203 | 204 | return 0; 205 | } 206 | -------------------------------------------------------------------------------- /ext/sbb_aff/graphics/nums.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Nums : 64x64t, 8bpp, SBB-layout, not compressed. 3 | # 4 | -gt -gB8 5 | -------------------------------------------------------------------------------- /ext/sbb_aff/graphics/nums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/sbb_aff/graphics/nums.png -------------------------------------------------------------------------------- /ext/sbb_aff/source/sbb_aff.c: -------------------------------------------------------------------------------- 1 | // 2 | // sbb_aff.c 3 | // showing screenblock boundaries for affine backgrounds 4 | // 5 | // (20031115 - 20080416, Cearn) 6 | // === NOTES === 7 | 8 | #include 9 | #include 10 | #include "nums.h" 11 | 12 | #define MAP_AFF_SIZE 0x0100 13 | 14 | // -------------------------------------------------------------------- 15 | // GLOBALS 16 | // -------------------------------------------------------------------- 17 | 18 | OBJ_ATTR *obj_cross= &oam_mem[0]; 19 | OBJ_ATTR *obj_disp= &oam_mem[1]; 20 | 21 | BG_AFFINE bgaff; 22 | 23 | // -------------------------------------------------------------------- 24 | // FUNCTIONS 25 | // -------------------------------------------------------------------- 26 | 27 | void win_textbox(int bgnr, int left, int top, int right, int bottom, int bldy) 28 | { 29 | REG_WIN0H= left<<8 | right; 30 | REG_WIN0V= top<<8 | bottom; 31 | REG_WIN0CNT= WIN_ALL | WIN_BLD; 32 | REG_WINOUTCNT= WIN_ALL; 33 | 34 | REG_BLDCNT= (BLD_ALL&~BIT(bgnr)) | BLD_BLACK; 35 | REG_BLDY= bldy; 36 | 37 | REG_DISPCNT |= DCNT_WIN0; 38 | 39 | tte_set_margins(left, top, right, bottom); 40 | } 41 | 42 | void init_cross() 43 | { 44 | TILE cross= 45 | {{ 46 | 0x00011100, 0x00100010, 0x01022201, 0x01021201, 47 | 0x01022201, 0x00100010, 0x00011100, 0x00000000, 48 | }}; 49 | tile_mem[4][1]= cross; 50 | 51 | pal_obj_mem[0x01]= pal_obj_mem[0x12]= CLR_WHITE; 52 | pal_obj_mem[0x02]= pal_obj_mem[0x11]= CLR_BLACK; 53 | 54 | obj_cross->attr2= 0x0001; 55 | obj_disp->attr2= 0x1001; 56 | } 57 | 58 | void init_map() 59 | { 60 | int ii; 61 | 62 | memcpy32(&tile8_mem[0][1], numsTiles, numsTilesLen/4); 63 | memcpy32(pal_bg_mem, numsPal, numsPalLen/4); 64 | 65 | REG_BG2CNT= BG_CBB(0) | BG_SBB(8) | BG_AFF_64x64; 66 | bgaff= bg_aff_default; 67 | 68 | // fill per 256 screen entries (=32x4 bands) 69 | u32 *pse= (u32*)se_mem[8]; 70 | u32 ses= 0x01010101; 71 | for(ii=0; ii<16; ii++) 72 | { 73 | memset32(pse, ses, MAP_AFF_SIZE/4); 74 | pse += MAP_AFF_SIZE/4; 75 | ses += 0x01010101; 76 | } 77 | } 78 | 79 | void sbb_aff() 80 | { 81 | AFF_SRC_EX asx= 82 | { 83 | 32<<8, 64<<8, // Map coords. 84 | 120, 80, // Screen coords. 85 | 0x0100, 0x0100, 0 // Scales and angle. 86 | }; 87 | 88 | const int DX=256; 89 | FIXED ss= 0x0100; 90 | 91 | while(1) 92 | { 93 | vid_vsync(); 94 | key_poll(); 95 | 96 | // dir + A : move map in screen coords 97 | if(key_is_down(KEY_A)) 98 | { 99 | asx.scr_x += key_tri_horz(); 100 | asx.scr_y += key_tri_vert(); 101 | } 102 | else // dir : move map in map coords 103 | { 104 | asx.tex_x -= DX*key_tri_horz(); 105 | asx.tex_y -= DX*key_tri_vert(); 106 | } 107 | // rotate 108 | asx.alpha -= 128*key_tri_shoulder(); 109 | 110 | 111 | // B: scale up ; B+Se : scale down 112 | if(key_is_down(KEY_B)) 113 | ss += (key_is_down(KEY_SELECT) ? -1 : 1); 114 | 115 | // St+Se : reset 116 | // St : toggle wrapping flag. 117 | if(key_hit(KEY_START)) 118 | { 119 | if(key_is_down(KEY_SELECT)) 120 | { 121 | asx.tex_x= asx.tex_y= 0; 122 | asx.scr_x= asx.scr_y= 0; 123 | asx.alpha= 0; 124 | ss= 1<<8; 125 | } 126 | else 127 | REG_BG2CNT ^= BG_WRAP; 128 | } 129 | 130 | asx.sx= asx.sy= (1<<16)/ss; 131 | 132 | bg_rotscale_ex(&bgaff, &asx); 133 | REG_BG_AFFINE[2]= bgaff; 134 | 135 | // the cross indicates the rotation point 136 | // (== p in map-space; q in screen-space) 137 | obj_set_pos(obj_cross, asx.scr_x-3, (asx.scr_y-3)); 138 | obj_set_pos(obj_disp, (bgaff.dx>>8)-3, (bgaff.dy>>8)-3); 139 | 140 | tte_printf("#{es;P}p0\t: (%d, %d)\nq0\t: (%d, %d)\ndx\t: (%d, %d)", 141 | asx.tex_x>>8, asx.tex_y>>8, asx.scr_x, asx.scr_y, 142 | bgaff.dx>>8, bgaff.dy>>8); 143 | } 144 | } 145 | 146 | int main() 147 | { 148 | init_map(); 149 | init_cross(); 150 | 151 | REG_DISPCNT= DCNT_MODE1 | DCNT_BG0 | DCNT_BG2 | DCNT_OBJ; 152 | 153 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 154 | tte_init_con(); 155 | win_textbox(0, 8, 120, 232, 156, 8); 156 | 157 | sbb_aff(); 158 | 159 | return 0; 160 | } 161 | -------------------------------------------------------------------------------- /ext/snd1_demo/source/snd1_demo.c: -------------------------------------------------------------------------------- 1 | // snd1_demo.c: 2 | // Beep! ^_^ 3 | // 4 | // (20060125 - 20060125, Cearn) 5 | // 6 | // === NOTES === 7 | // * TODO: strings for notes / octaves 8 | 9 | #include 10 | #include 11 | 12 | // ===DATA ============================================================ 13 | 14 | u8 txt_scrolly= 8; 15 | 16 | const char *names[]= 17 | { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " }; 18 | 19 | // === FUNCTIONS ====================================================== 20 | 21 | // Show the octave the next note will be in 22 | void note_prep(int octave) 23 | { 24 | tte_printf("#{P:8,%d;cx:0x1000}[ %+2d]", txt_scrolly, octave); 25 | } 26 | 27 | 28 | // Play a note and show which one was played 29 | void note_play(int note, int octave) 30 | { 31 | // Clear next top and current rows 32 | SBB_CLEAR_ROW(31, (txt_scrolly/8-2)&31); 33 | SBB_CLEAR_ROW(31, txt_scrolly/8); 34 | 35 | // Display note and scroll 36 | tte_printf("#{P:16,%d;cx:0}%-2s%+2d", txt_scrolly, names[note], octave); 37 | //se_puts(16, txt_scrolly, str, 0); 38 | 39 | txt_scrolly -= 8; 40 | REG_BG0VOFS= txt_scrolly-8; 41 | 42 | // Play the actual note 43 | REG_SND1FREQ = SFREQ_RESET | SND_RATE(note, octave); 44 | } 45 | 46 | 47 | // Play a little ditty 48 | void sos() 49 | { 50 | const u8 lens[6]= { 1,1,4, 1,1,4 }; 51 | const u8 notes[6]= { 0x02, 0x05, 0x12, 0x02, 0x05, 0x12 }; 52 | int ii; 53 | for(ii=0; ii<6; ii++) 54 | { 55 | note_play(notes[ii]&15, notes[ii]>>4); 56 | VBlankIntrDelay(8*lens[ii]); 57 | } 58 | } 59 | 60 | int main() 61 | { 62 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 63 | 64 | irq_init(NULL); 65 | irq_add(II_VBLANK, NULL); 66 | 67 | tte_init_se(0, BG_CBB(0) | BG_SBB(31), 0, CLR_ORANGE, 0, NULL, NULL); 68 | tte_init_con(); 69 | pal_bg_mem[0x11]= CLR_GREEN; 70 | 71 | int octave= 0; 72 | 73 | // turn sound on 74 | REG_SNDSTAT= SSTAT_ENABLE; 75 | // snd1 on left/right ; both full volume 76 | REG_SNDDMGCNT = SDMG_BUILD_LR(SDMG_SQR1, 7); 77 | // DMG ratio to 100% 78 | REG_SNDDSCNT= SDS_DMG100; 79 | 80 | // no sweep 81 | REG_SND1SWEEP= SSW_OFF; 82 | // envelope: vol=12, decay, max step time (7) ; 50% duty 83 | REG_SND1CNT= SSQR_ENV_BUILD(12, 0, 7) | SSQR_DUTY1_2; 84 | REG_SND1FREQ= 0; 85 | 86 | sos(); 87 | 88 | while(1) 89 | { 90 | VBlankIntrWait(); 91 | key_poll(); 92 | 93 | // Change octave: 94 | octave += bit_tribool(key_hit(-1), KI_R, KI_L); 95 | octave= wrap(octave, -2, 6); 96 | note_prep(octave); 97 | 98 | // Play note 99 | if(key_hit(KEY_DIR|KEY_A)) 100 | { 101 | if(key_hit(KEY_UP)) 102 | note_play(NOTE_D, octave+1); 103 | if(key_hit(KEY_LEFT)) 104 | note_play(NOTE_B, octave); 105 | if(key_hit(KEY_RIGHT)) 106 | note_play(NOTE_A, octave); 107 | if(key_hit(KEY_DOWN)) 108 | note_play(NOTE_F, octave); 109 | if(key_hit(KEY_A)) 110 | note_play(NOTE_D, octave); 111 | } 112 | 113 | // Play ditty 114 | if(key_hit(KEY_B)) 115 | sos(); 116 | } 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /ext/swi_demo/source/swi_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // swi_demo.c 3 | // 4 | // Demonstrates software interrupt 5 | // Note that swi.c uses inline assembly, which is 6 | // compiler dependent. The THUMB/ARM thing is nicely 7 | // circumvented by defining the swi_call macro. 8 | // 9 | // (20031228 - 20070809, Cearn) 10 | 11 | #include 12 | #include 13 | 14 | // === swi calls ====================================================== 15 | 16 | /* 17 | //# NOTE, 20120520 : inline ASM functions now pretty much require 18 | //# proper register-input/output matching, so these don't work anymore. 19 | 20 | // Their assembly equivalents can be found in tonc_bios.s 21 | 22 | void VBlankIntrWait() 23 | { swi_call(0x05); } 24 | 25 | int Div(int num, int denom) 26 | { 27 | s32 result; 28 | swi_call_r0(0x06, result); 29 | return result; 30 | //swi_call(0x06); 31 | } 32 | 33 | u32 Sqrt(u32 num) 34 | { swi_call(0x08); } 35 | 36 | s16 ArcTan2(s16 x, s16 y) 37 | { swi_call(0x0a); } 38 | 39 | void ObjAffineSet(const AFF_SRC *src, void *dst, int num, int offset) 40 | { swi_call(0x0f); } 41 | */ 42 | 43 | 44 | // === swi demos ====================================================== 45 | 46 | // NOTE! 47 | // To be consistent with general mathematical graphs, the 48 | // y-axis has to be reversed and the origin moved to the 49 | // either the bottom or mid of the screen via 50 | // "iy = H - y" 51 | // or 52 | // "iy = H/2 - y" 53 | // 54 | // functions have been scaled to fit the graphs on the 240x160 screen 55 | 56 | // y= 2560/x 57 | void div_demo() 58 | { 59 | int ix, y; 60 | ASM_BREAK(); 61 | 62 | for(ix=1; ix>16; 65 | if(y <= SCREEN_HEIGHT) 66 | m3_plot(ix, SCREEN_HEIGHT - y, CLR_RED); 67 | } 68 | tte_printf("#{P:168,132;ci:%d}div", CLR_RED); 69 | } 70 | 71 | // y= 160*sqrt(x/240) 72 | void sqrt_demo() 73 | { 74 | int ix, y; 75 | for(ix=0; ix 85 | void arctan2_demo() 86 | { 87 | int ix, y; 88 | int ww= SCREEN_WIDTH/2, hh= SCREEN_HEIGHT/2; 89 | for(ix=0; ix < SCREEN_WIDTH; ix++) 90 | { 91 | y= ArcTan2(0x10, ix-ww); 92 | m3_plot(ix, hh - y/256, CLR_MAG); 93 | } 94 | tte_printf("#{P:144,40;ci:%d}atan", CLR_MAG); 95 | 96 | // pick some random memory to show the range of arctan2 97 | OBJ_ATTR *obj= &oam_mem[4]; 98 | obj->attr0= ArcTan2( 0x100, 0x100); // q0 : 0x2000 (pi*1/4) 99 | obj->attr1= ArcTan2(-0x100, 0x100); // q1 : 0x6000 (pi*3/4) 100 | obj->attr2= ArcTan2(-0x100, -0x100); // q2 : 0xa000 (pi*5/4 = pi*-3/4) 101 | obj->fill= ArcTan2( 0x100, -0x100); // q3 : 0xe000 (pi*7/4 = pi*-1/4) 102 | } 103 | 104 | // wX= 1, wY= 80 105 | // cc= 80*sx*cos(2*pi*alpha/240) 106 | // ss= 1*sy*sin(2*pi*alpha/240) 107 | void aff_demo() 108 | { 109 | int ix, ss, cc; 110 | ObjAffineSource af_src= {0x0100, 0x5000, 0}; // sx=1, sy=80, alpha=0 111 | ObjAffineDest af_dest= {0x0100, 0, 0, 0x0100}; // =I (redundant) 112 | 113 | for(ix=0; ix>8; 117 | ss= af_dest.pc>>8; 118 | m3_plot(ix, 80 - cc, CLR_YELLOW); 119 | m3_plot(ix, 80 - ss, CLR_CYAN); 120 | // 0x010000/0xf0 = 0x0111.111... 121 | af_src.alpha += 0x0111; // acceptable rounding error 122 | } 123 | 124 | tte_printf("#{P:48,38;ci:%d}cos", CLR_YELLOW); 125 | tte_printf("#{P:72,20;ci:%d}sin", CLR_CYAN); 126 | } 127 | 128 | // === main =========================================================== 129 | 130 | int main() 131 | { 132 | REG_DISPCNT= DCNT_MODE3 | DCNT_BG2; 133 | 134 | tte_init_bmp_default(3); 135 | tte_init_con(); 136 | 137 | div_demo(); 138 | sqrt_demo(); 139 | aff_demo(); 140 | 141 | arctan2_demo(); 142 | 143 | while(1); 144 | 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /ext/swi_vsync/graphics/metr.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Metroid : 4bpp, not compressed. Only use the last 64 columns. 3 | # 4 | -gB4 -al64 5 | -------------------------------------------------------------------------------- /ext/swi_vsync/graphics/metr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/swi_vsync/graphics/metr.png -------------------------------------------------------------------------------- /ext/swi_vsync/source/swi_vsync.c: -------------------------------------------------------------------------------- 1 | // 2 | // swi_vsync.c 3 | // Vsyncing with BIOS call 5 4 | // 5 | // (Created: 20040602 - 20060928, Cearn) 6 | 7 | #include 8 | #include "metr.h" 9 | 10 | void init_main() 11 | { 12 | // The obvious initialisations 13 | REG_DISPCNT= DCNT_OBJ | DCNT_OBJ_1D; 14 | oam_init(oam_mem, 128); 15 | 16 | // Get the tiles & palette 17 | memcpy32(&tile_mem[4][0], metrTiles, metrTilesLen/4); 18 | memcpy32(pal_obj_mem, metrPal, metrPalLen/4); 19 | 20 | // Initialize the metroid sprite 21 | OBJ_ATTR *metr= &oam_mem[0]; 22 | obj_set_attr(metr, ATTR0_SQUARE | ATTR0_AFF_DBL, 23 | ATTR1_SIZE_64 | ATTR1_AFF_ID(0), 0); 24 | obj_set_pos(metr, 120-64, 80-64); 25 | } 26 | 27 | int main() 28 | { 29 | AFF_SRC as= { 0x0100, 0x0100, 0 }; 30 | OBJ_AFFINE oaff; 31 | 32 | init_main(); 33 | 34 | // Init interrupts, and enable VBlank irq 35 | irq_init(NULL); 36 | irq_add(II_VBLANK, NULL); 37 | 38 | while(1) 39 | { 40 | VBlankIntrWait(); 41 | 42 | // Full circle = 10000h 43 | // 10000h/4/60= 111h -> 1/4 rev/s = 1 passing corner/s 44 | as.alpha += 0x0111; 45 | ObjAffineSet(&as, &oaff.pa, 1, OBJ_AFF_OFS); 46 | 47 | obj_aff_copy(obj_aff_mem, &oaff, 1); 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /ext/tmr_demo/berk.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/tmr_demo/berk.bmp -------------------------------------------------------------------------------- /ext/tmr_demo/berk.txt: -------------------------------------------------------------------------------- 1 | Berka! Berka! Berka! 2 | berk.gif font from headsipn's collection. 3 | -------------------------------------------------------------------------------- /ext/tmr_demo/graphics/berk.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Berk : 64x64t, 4bpp, flat-layout, no map reduction, not compressed. 3 | # 4 | -gt -gB4 -mR! -mLf 5 | -------------------------------------------------------------------------------- /ext/tmr_demo/graphics/berk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/tmr_demo/graphics/berk.png -------------------------------------------------------------------------------- /ext/tmr_demo/source/tmr_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // tmr_demo.c 3 | // Demonstrating a cascade timer 4 | // Using a slightly modified version of berk.gif from Headspin's fonts. 5 | // Press start to start timer. 6 | // 7 | // (20031220 -20070809, Cearn) 8 | // (20221113, AntonioND) 9 | 10 | #include 11 | #include 12 | 13 | #include "berk.h" 14 | 15 | // Grit exports a tile array in which the first tile is empty. This gives us a 16 | // pointer to the first tile with data. 17 | #define TILE_SIZE (8 * 8 / 2) 18 | #define TILES_START (berkTiles + TILE_SIZE / sizeof(berkTiles[0])) 19 | 20 | const TFont berkFont= 21 | { 22 | TILES_START, 0, 0, 23 | 48, 11, 24 | 24, 40, 25 | 24, 40, 480, 26 | 4, 0, 27 | }; 28 | 29 | void tmr_test() 30 | { 31 | // Overflow every ~1 second: 32 | // 0x4000 ticks @ FREQ_1024 33 | 34 | REG_TM2D= -0x4000; // 0x4000 ticks till overflow 35 | REG_TM2CNT= TM_FREQ_1024; // we're using the 1024 cycle timer 36 | 37 | // cascade into tm3 38 | REG_TM3CNT= TM_ENABLE | TM_CASCADE; 39 | 40 | u32 sec= -1; 41 | 42 | while(1) 43 | { 44 | vid_vsync(); 45 | key_poll(); 46 | 47 | if(REG_TM3D != sec) 48 | { 49 | sec= REG_TM3D; 50 | tte_printf("#{es;P:24,60}%02d:%02d:%02d", 51 | sec/3600, (sec%3600)/60, sec%60); 52 | } 53 | 54 | if(key_hit(KEY_START)) // pause by disabling timer 55 | REG_TM2CNT ^= TM_ENABLE; 56 | 57 | if(key_hit(KEY_SELECT)) // pause by enabling cascade 58 | REG_TM2CNT ^= TM_CASCADE; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | // set-up berk font 65 | tte_init_se(0, BG_CBB(0)|BG_SBB(31), 1, 0, 0, &berkFont, se_drawg); 66 | tte_init_con(); 67 | memcpy16(pal_bg_mem, berkPal, berkPalLen/4); 68 | 69 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 70 | 71 | tmr_test(); 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /ext/win_demo/graphics/nums.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Nums : 64x64t, 8bpp, SBB-layout, not compressed. 3 | # 4 | -gt -gB8 5 | -------------------------------------------------------------------------------- /ext/win_demo/graphics/nums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/win_demo/graphics/nums.png -------------------------------------------------------------------------------- /ext/win_demo/graphics/rocket.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Metroid : 4bpp, not compressed. 3 | # 4 | -gB4 5 | -------------------------------------------------------------------------------- /ext/win_demo/graphics/rocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/ext/win_demo/graphics/rocket.png -------------------------------------------------------------------------------- /ext/win_demo/source/win_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // win_demo.c 3 | // Playing hide and seek with a rocket item 4 | // using windowing 5 | // 6 | // (20040104 - 20060926, cearn) 7 | // === NOTES === 8 | // bg 0, cbb 0, sbb 2, pb 0: numbered forground 9 | // bg 1, cbb 0, sbb 3, pb 0: fenced background 10 | // oam 0: tile 0-3: rocket 11 | 12 | // win 0: objects 13 | // win 1: bg 0 14 | // win out : bg 1 15 | 16 | #include 17 | #include "nums.h" 18 | #include "rocket.h" 19 | 20 | #define ROCKET_OID 0 21 | 22 | 23 | // --- global buffers for window registers --- 24 | // This will allow you to poke them inside IWRAM, 25 | // since you can't poke REG_WINx directly. :( 26 | 27 | typedef struct tagRECT_U8 { u8 ll, tt, rr, bb; } RECT_U8; 28 | 29 | // Objects in win0, BG in win1 30 | RECT_U8 win[2]= 31 | { 32 | { 36, 20, 76, 60 }, // win0: 40x40 rect 33 | { 12, 12 ,228, 148 } // win1: screen minus 12 margin. 34 | }; 35 | 36 | // foreground map is alternating numbered tile pattern 37 | // is inside window 1 38 | void init_front_map() 39 | { 40 | int ii, jj; 41 | 42 | memcpy32(&tile8_mem[0][1], numsTiles, numsTilesLen/4); 43 | memcpy32(pal_bg_mem, numsPal, numsPalLen/4); 44 | pal_bg_mem[0]= CLR_BLACK; 45 | 46 | u16 *pse= &se_mem[2][0]; 47 | for(ii=0; ii<20; ii++) 48 | for(jj=0; jj<32; jj++) 49 | *pse++= ((ii+jj)&0x0F)+1; 50 | 51 | REG_BG0CNT= BG_CBB(0) | BG_SBB(2) | BG_8BPP; 52 | } 53 | 54 | // fill a second background with a (not so) nice thread pattern 55 | // is on outside 56 | void init_back_map() 57 | { 58 | const TILE back_tile= 59 | {{ 60 | 0x33123333, 0x33123333, 0x13213331, 0x21212112, 61 | 0x12121221, 0x33123332, 0x33213333, 0x33213333 62 | }}; 63 | 64 | tile_mem[0][0x30]= back_tile; 65 | 66 | pal_bg_mem[0x21]= 0x09BA; 67 | pal_bg_mem[0x22]= 0xC0DE; 68 | pal_bg_mem[0x23]= 0x0015; 69 | pal_bg_mem[0x24]= 0xC001; 70 | 71 | u32 ses= 0x30 | SE_PALBANK(2); // tile 0x30, pal-bank 2 72 | ses |= (ses | SE_HFLIP | SE_VFLIP)<<16; 73 | 74 | memset32(&se_mem[3][0], ses, 32*20/2); 75 | 76 | REG_BG1CNT= BG_CBB(0) | BG_SBB(3); 77 | } 78 | 79 | // rocket is inside window 0 80 | void init_rocket() 81 | { 82 | memcpy32(&tile_mem[4][0], rocketTiles, rocketTilesLen/4); 83 | memcpy32(pal_obj_mem, rocketPal, rocketPalLen/4); 84 | 85 | OBJ_ATTR *rocket= &oam_mem[ROCKET_OID]; 86 | obj_set_attr(rocket, ATTR0_SQUARE, ATTR1_SIZE_16, 0); 87 | obj_set_pos(rocket, 96, 32); 88 | } 89 | 90 | void win_copy() 91 | { 92 | REG_WIN0H= win[0].ll<<8 | win[0].rr; 93 | REG_WIN1H= win[1].ll<<8 | win[1].rr; 94 | REG_WIN0V= win[0].tt<<8 | win[0].bb; 95 | REG_WIN1V= win[1].tt<<8 | win[1].bb; 96 | } 97 | 98 | void test_win() 99 | { 100 | win_copy(); 101 | while(1) 102 | { 103 | key_poll(); 104 | vid_vsync(); 105 | 106 | // key_hit() or key_is_down() 'switch' 107 | // A depressed: move on direction press (std movement) 108 | // A pressed : moves on direction hit (fine movement) 109 | int keys= key_curr_state(); 110 | if(key_is_down(KEY_A)) 111 | keys &= ~key_prev_state(); 112 | 113 | if(keys & KEY_RIGHT) 114 | { win[0].ll++; win[0].rr++; } 115 | else if(keys & KEY_LEFT ) 116 | { win[0].ll--; win[0].rr--; } 117 | if(keys & KEY_DOWN) 118 | { win[0].tt++; win[0].bb++; } 119 | else if(keys & KEY_UP ) 120 | { win[0].tt--; win[0].bb--; } 121 | 122 | // randomize rocket position 123 | if(key_hit(KEY_START)) 124 | obj_set_pos(&oam_mem[ROCKET_OID], 125 | qran_range(0, 232), qran_range(0, 152)); 126 | 127 | win_copy(); 128 | } 129 | } 130 | 131 | int main() 132 | { 133 | // obvious inits 134 | oam_init(oam_mem, 128); 135 | init_front_map(); 136 | init_back_map(); 137 | init_rocket(); 138 | win_copy(); 139 | 140 | // windowing inits 141 | //win_init(DCNT_WIN0 | DCNT_WIN1); 142 | REG_DISPCNT= DCNT_BG0 | DCNT_BG1 | DCNT_OBJ | 143 | DCNT_OBJ_1D | DCNT_WIN0 | DCNT_WIN1; 144 | 145 | REG_WININ= WININ_BUILD(WIN_OBJ, WIN_BG0); 146 | REG_WINOUT= WINOUT_BUILD(WIN_BG1, 0); 147 | 148 | test_win(); 149 | 150 | return 0; 151 | } 152 | -------------------------------------------------------------------------------- /lab/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS:= `ls` 2 | 3 | all: 4 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i || { exit 1;} fi; done; 5 | clean: 6 | @for i in $(SUBDIRS); do if test -e $$i/Makefile ; then $(MAKE) -C $$i clean || { exit 1;} fi; done; 7 | -------------------------------------------------------------------------------- /lab/bigmap/graphics/kakariko.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Kakariko : 4bpp, flat-layout, LZ77 compressed (only the tiles). 3 | # 4 | -gt -gB4 -mR4 -mLf -Zl -gz -mz! -pz! 5 | -------------------------------------------------------------------------------- /lab/bigmap/graphics/kakariko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/lab/bigmap/graphics/kakariko.png -------------------------------------------------------------------------------- /lab/bigmap/graphics/link_gfx.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Link GFX : 4bpp, not compressed. Metatiles of 2x2 tiles. Only 128x48 pixels. 3 | # 4 | -gB4 -Mw2 -Mh2 -aw128 -ah48 5 | -------------------------------------------------------------------------------- /lab/bigmap/graphics/link_gfx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/lab/bigmap/graphics/link_gfx.png -------------------------------------------------------------------------------- /lab/bigmap/source/bigmap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Big map scrolling and sprite animation 3 | // 4 | //! \file bigmap.c 5 | //! \author J Vijn 6 | //! \date 20060508 - 20070216 7 | // 8 | // === NOTES === 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "link.h" 16 | 17 | #include "kakariko.h" 18 | #include "link_gfx.h" 19 | 20 | 21 | #define kakarikoMapPitch 128 22 | 23 | // === CONSTANTS ====================================================== 24 | // === CLASSES ======================================================== 25 | 26 | 27 | // TODO: rename structs and members 28 | 29 | typedef struct VIEWPORT 30 | { 31 | int x, xmin, xmax, xpage; 32 | int y, ymin, ymax, ypage; 33 | } VIEWPORT; 34 | 35 | 36 | typedef struct TMapInfo 37 | { 38 | union 39 | { 40 | u32 state; //!< Background state 41 | struct 42 | { 43 | u16 flags; 44 | u16 cnt; 45 | }; 46 | }; 47 | // Destination data 48 | SCR_ENTRY *dstMap; //!< Screenblock pointer 49 | // Source data 50 | SCR_ENTRY *srcMap; //!< Source map address 51 | u32 srcMapWidth; //!< Source map width 52 | u32 srcMapHeight; //!< Source map height 53 | FIXED mapX; //!< X-coord on map (.8f) 54 | FIXED mapY; //!< Y-coord on map (.8f) 55 | } TMapInfo; 56 | 57 | 58 | // === GLOBALS ======================================================== 59 | 60 | 61 | VIEWPORT g_vp= 62 | { 63 | 0, 0, 1024, 240, 64 | 0, 0, 1024, 160, 65 | }; 66 | 67 | TMapInfo g_bg; 68 | 69 | OBJ_ATTR obj_buffer[128]; 70 | 71 | TSprite g_link; 72 | 73 | 74 | // === PROTOTYPES ===================================================== 75 | 76 | INLINE void vp_center(VIEWPORT *vp, int x, int y); 77 | void vp_set_pos(VIEWPORT *vp, int x, int y); 78 | 79 | // === MACROS ========================================================= 80 | // === INLINES========================================================= 81 | // === FUNCTIONS ====================================================== 82 | 83 | 84 | // --- VIEWPORT --- 85 | 86 | INLINE void vp_center(VIEWPORT *vp, int x, int y) 87 | { vp_set_pos(vp, x - vp->xpage/2, y - vp->ypage/2); } 88 | 89 | 90 | void vp_set_pos(VIEWPORT *vp, int x, int y) 91 | { 92 | vp->x= clamp(x, vp->xmin, vp->xmax - vp->xpage); 93 | vp->y= clamp(y, vp->ymin, vp->ymax - vp->ypage); 94 | } 95 | 96 | 97 | // --- TMapInfo --- 98 | 99 | void bgt_init(TMapInfo *bgt, int bgnr, u32 ctrl, 100 | const void *map, u32 map_width, u32 map_height) 101 | { 102 | memset(bgt, 0, sizeof(TMapInfo)); 103 | 104 | bgt->flags= bgnr; 105 | bgt->cnt= ctrl; 106 | bgt->dstMap= se_mem[BFN_GET(ctrl, BG_SBB)]; 107 | 108 | REG_BGCNT[bgnr]= ctrl; 109 | REG_BG_OFS[bgnr].x= 0; 110 | REG_BG_OFS[bgnr].y= 0; 111 | 112 | 113 | bgt->srcMap= (SCR_ENTRY*)map; 114 | bgt->srcMapWidth= map_width; 115 | bgt->srcMapHeight= map_height; 116 | 117 | int ix, iy; 118 | SCR_ENTRY *dst= bgt->dstMap, *src= bgt->srcMap; 119 | for(iy=0; iy<32; iy++) 120 | for(ix=0; ix<32; ix++) 121 | dst[iy*32+ix]= src[ iy*bgt->srcMapWidth+ix]; 122 | } 123 | 124 | void bgt_colcpy(TMapInfo *bgt, int tx, int ty) 125 | { 126 | int iy, y0= ty&31; 127 | 128 | int srcP= bgt->srcMapWidth; 129 | SCR_ENTRY *srcL= &bgt->srcMap[ty*srcP + tx]; 130 | SCR_ENTRY *dstL= &bgt->dstMap[y0*32 + (tx&31)]; 131 | 132 | for(iy=y0; iy<32; iy++) 133 | { *dstL= *srcL; dstL += 32; srcL += srcP; } 134 | 135 | dstL -= 1024; 136 | 137 | for(iy=0; iysrcMapWidth; 146 | SCR_ENTRY *srcL= &bgt->srcMap[ty*srcP + tx]; 147 | SCR_ENTRY *dstL= &bgt->dstMap[(ty&31)*32 + x0]; 148 | 149 | for(ix=x0; ix<32; ix++) 150 | *dstL++= *srcL++; 151 | 152 | dstL -= 32; 153 | 154 | for(ix=0; ixx, vy= vp->y; 162 | int bx= bgt->mapX, by= bgt->mapY; 163 | 164 | // Tile coords 165 | int tvx= vx>>3, tvy= vy>>3; 166 | int tbx= bx>>3, tby= by>>3; 167 | 168 | // Basically, we need another row/col when the viewport 169 | // exposes another row/col, i.e., if the tile coords 170 | // have changed 171 | 172 | if(tvx < tbx) // add on left 173 | bgt_colcpy(bgt, tvx, tvy); 174 | else if(tvx > tbx) // add on right 175 | bgt_colcpy(bgt, tvx+31, tvy); 176 | 177 | if(tvy < tby) // add on top 178 | bgt_rowcpy(bgt, tvx, tvy); 179 | else if(tvy > tby) // add on bottom 180 | bgt_rowcpy(bgt, tvx, tvy+31); 181 | 182 | // Update TMapInfo and reg-offsets 183 | int bgnr= bgt->flags; 184 | REG_BG_OFS[bgnr].x= bgt->mapX= vx; 185 | REG_BG_OFS[bgnr].y= bgt->mapY= vy; 186 | } 187 | 188 | void init_textbox(int bgnr, int left, int top, int right, int bottom) 189 | { 190 | tte_set_margins(left, top, right, bottom); 191 | 192 | REG_DISPCNT |= DCNT_WIN0; 193 | 194 | REG_WIN0H= left<<8 | right; 195 | REG_WIN0V= top<<8 | bottom; 196 | REG_WIN0CNT= WIN_ALL | WIN_BLD; 197 | REG_WINOUTCNT= WIN_ALL; 198 | 199 | REG_BLDCNT= (BLD_ALL&~BIT(bgnr)) | BLD_BLACK; 200 | REG_BLDY= 5; 201 | } 202 | 203 | void init_main() 204 | { 205 | // Basic setups 206 | irq_init(NULL); 207 | irq_add(II_VBLANK, NULL); 208 | oam_init(obj_buffer, 128); 209 | 210 | // Bigmap setup 211 | LZ77UnCompVram(kakarikoTiles, tile_mem[0]); 212 | GRIT_CPY(pal_bg_mem, kakarikoPal); 213 | 214 | bgt_init(&g_bg, 1, BG_CBB(0)|BG_SBB(29), kakarikoMap, 215 | 128, 128); 216 | 217 | // Object setup 218 | GRIT_CPY(pal_obj_mem, link_gfxPal); 219 | GRIT_CPY(tile_mem[4], link_gfxTiles); 220 | 221 | link_init(&g_link, int2fx(120), int2fx(80), 0); 222 | 223 | //# NOTE: erasing and rendering text flows over into the VDRAW period. 224 | //# Using the ASM renderer and placing the text at the bottom limits its effects. 225 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 226 | tte_set_drawg(chr4c_drawg_b4cts_fast); 227 | tte_init_con(); 228 | 229 | //init_textbox(0, 8, 8, SCR_W-8, 8+2*12); 230 | 231 | init_textbox(0, 8, SCR_H-(8+2*12), SCR_W-8, SCR_H-8); 232 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_OBJ | 233 | DCNT_OBJ_1D | DCNT_WIN0; 234 | } 235 | 236 | int main() 237 | { 238 | init_main(); 239 | 240 | int x, y; 241 | 242 | while(1) 243 | { 244 | VBlankIntrWait(); 245 | 246 | key_poll(); 247 | 248 | link_input(&g_link); 249 | link_animate(&g_link); 250 | link_move(&g_link); 251 | 252 | x= fx2int(g_link.x), y= fx2int(g_link.y); 253 | 254 | vp_center(&g_vp, x, y); 255 | oam_copy(oam_mem, obj_buffer, 128); 256 | 257 | bgt_update(&g_bg, &g_vp); 258 | 259 | tte_printf("#{es;P}( x, y) = (%d,%d)\n(vx,vy) = (%d,%d)", 260 | x, y, g_vp.x, g_vp.y); 261 | pal_bg_mem[0]= REG_VCOUNT; 262 | } 263 | 264 | return 0; 265 | } 266 | 267 | // EOF 268 | -------------------------------------------------------------------------------- /lab/bigmap/source/link.c: -------------------------------------------------------------------------------- 1 | // 2 | // Link movement 3 | // 4 | //! \file link.c 5 | //! \author J Vijn 6 | //! \date 20070216 - 20070216 7 | // 8 | // === NOTES === 9 | // * Code is done for shortness and ease of use, 10 | // not necessarily speed. 11 | 12 | #include 13 | 14 | #include "link.h" 15 | 16 | #define LINK_SPEED 0x0180 17 | 18 | // -------------------------------------------------------------------- 19 | // EXTERNAL 20 | // -------------------------------------------------------------------- 21 | 22 | typedef struct VIEWPORT 23 | { 24 | int x, xmin, xmax, xpage; 25 | int y, ymin, ymax, ypage; 26 | } VIEWPORT; 27 | 28 | extern VIEWPORT g_vp; 29 | extern OBJ_ATTR obj_buffer[]; 30 | 31 | // -------------------------------------------------------------------- 32 | // DECLARATIONS 33 | // -------------------------------------------------------------------- 34 | 35 | static void link_ani_stand(TSprite *link); 36 | static void link_ani_walk(TSprite *link); 37 | 38 | // -------------------------------------------------------------------- 39 | // LUTS 40 | // -------------------------------------------------------------------- 41 | 42 | const u8 cLookDirs[4]= { 0, 1, 0, 2 }; 43 | 44 | const s8 cLinkShadow[4][2]= 45 | { { 1, 9 }, { 0, 8 }, { -1, 9 }, { 0, 8 } }; 46 | 47 | 48 | const s8 cLinkStand[4]= { 32, 24, 32, 28}; 49 | 50 | 51 | // Movement luts 52 | const s8 cLinkHeadYs[3][8]= 53 | { 54 | { -8, -9, -9, -8, -8, -9, -9, -8 }, 55 | { -8, -9, -10, -8, -8, -9, -10, -8 }, 56 | { -8, -9, -10, -8, -8, -9, -10, -8 } 57 | }; 58 | 59 | const s8 cLinkHeadIds[3][8]= 60 | { 61 | { 4, 4, 16, 20, 4, 4, 16, 20 }, 62 | { 8, 8, 8, 8, 8, 8, 8, 8 }, 63 | { 12, 12, 12, 12, 12, 12, 12, 12 } 64 | }; 65 | 66 | const s8 cLinkBodyIds[3][8]= 67 | { 68 | { 32, 36, 40, 44, 48, 52, 56, 60, }, 69 | { 64, 68, 72, 76, 64, -68, -72, -76, }, 70 | { 80, 84, 88, 92, -80, -84, -88, -92 } 71 | }; 72 | 73 | // Default link attributes 74 | const OBJ_ATTR cLinkObjs[3]= 75 | { 76 | { 0, ATTR1_SIZE_16, 4, 0 }, 77 | { 8, ATTR1_SIZE_16+1, 32, 0 }, 78 | { ATTR0_WIDE+17, ATTR1_SIZE_8+1, 2, 0 } 79 | }; 80 | 81 | 82 | // -------------------------------------------------------------------- 83 | // FUNCTIONS 84 | // -------------------------------------------------------------------- 85 | 86 | void link_init(TSprite *link, FIXED x, FIXED y, int obj_id) 87 | { 88 | link->x= x; 89 | link->y= y; 90 | link->vx= link->vy= 0; 91 | 92 | link_set_state(link, SPR_STATE_STAND); 93 | link->dir= LOOK_RIGHT; 94 | link->objId= obj_id; 95 | 96 | oam_copy(&obj_buffer[obj_id], cLinkObjs, 3); 97 | } 98 | 99 | void link_set_state(TSprite *link, u32 state) 100 | { 101 | link->state= state; 102 | link->aniFrame= 0; 103 | } 104 | 105 | void link_input(TSprite *link) 106 | { 107 | link->vx= link->vy= 0; 108 | 109 | if( key_is_down(KEY_RIGHT) ) 110 | { 111 | link->vx= LINK_SPEED; 112 | link->dir= LOOK_RIGHT; 113 | } 114 | else if( key_is_down(KEY_LEFT) ) 115 | { 116 | link->vx= -LINK_SPEED; 117 | link->dir= LOOK_LEFT; 118 | } 119 | 120 | if( key_is_down(KEY_DOWN) ) 121 | { 122 | link->vy= LINK_SPEED; 123 | link->dir= LOOK_DOWN; 124 | } 125 | else if( key_is_down(KEY_UP) ) 126 | { 127 | link->vy= -LINK_SPEED; 128 | link->dir= LOOK_UP; 129 | } 130 | 131 | if( !key_is_down(KEY_DIR) ) 132 | link_set_state(link, SPR_STATE_STAND); 133 | 134 | if( key_hit(KEY_DIR) ) 135 | link_set_state(link, SPR_STATE_WALK); 136 | } 137 | 138 | void link_move(TSprite *link) 139 | { 140 | // TODO : collision testing here? 141 | 142 | link->x += link->vx; 143 | link->y += link->vy; 144 | } 145 | 146 | void link_animate(TSprite *link) 147 | { 148 | 149 | switch(link->state) 150 | { 151 | case SPR_STATE_STAND: 152 | link_ani_stand(link); 153 | break; 154 | case SPR_STATE_WALK: 155 | link->aniFrame += 0x56; 156 | link_ani_walk(link); 157 | } 158 | } 159 | 160 | static void link_ani_stand(TSprite *link) 161 | { 162 | POINT pt= { fx2int(link->x) - g_vp.x, fx2int(link->y) - g_vp.y }; 163 | OBJ_ATTR *obj= &obj_buffer[link->objId]; 164 | 165 | int dir= link->dir; 166 | int sublut= cLookDirs[dir]; 167 | 168 | // Set body 169 | BFN_SET(obj[1].attr0, pt.y, ATTR0_Y); 170 | 171 | obj[1].attr1 &= ~(ATTR1_HFLIP | ATTR1_X_MASK); 172 | obj[1].attr1 |= BFN_PREP(pt.x, ATTR1_X); 173 | if(dir == LOOK_LEFT) 174 | obj[1].attr1 |= ATTR1_HFLIP; 175 | 176 | obj[1].attr2= cLinkStand[dir]; 177 | 178 | // Set shadow 179 | obj_set_pos(&obj[2], 180 | pt.x + cLinkShadow[dir][0], 181 | pt.y + cLinkShadow[dir][1]); 182 | 183 | // Set head 184 | BFN_SET(obj[0].attr0, pt.y+cLinkHeadYs[sublut][0], ATTR0_Y); 185 | 186 | obj[0].attr1 &= ~(ATTR1_HFLIP | ATTR1_X_MASK); 187 | obj[0].attr1 |= BFN_PREP(pt.x-cLinkShadow[dir][0], ATTR1_X); 188 | 189 | if(dir == LOOK_LEFT) 190 | obj[0].attr1 |= ATTR1_HFLIP; 191 | 192 | obj[0].attr2= cLinkHeadIds[sublut][0]; 193 | } 194 | 195 | 196 | static void link_ani_walk(TSprite *link) 197 | { 198 | int dir= link->dir; 199 | int sublut= cLookDirs[dir]; 200 | int frame= fx2int(link->aniFrame) & 7; 201 | int tid; 202 | 203 | POINT pt= { fx2int(link->x) - g_vp.x, fx2int(link->y) - g_vp.y }; 204 | OBJ_ATTR *obj= &obj_buffer[link->objId]; 205 | 206 | 207 | // Set body 208 | BFN_SET(obj[1].attr0, pt.y, ATTR0_Y); 209 | 210 | obj[1].attr1 &= ~(ATTR1_HFLIP | ATTR1_X_MASK); 211 | obj[1].attr1 |= BFN_PREP(pt.x, ATTR1_X); 212 | if(dir == LOOK_LEFT) 213 | obj[1].attr1 |= ATTR1_HFLIP; 214 | 215 | tid= cLinkBodyIds[sublut][frame]; 216 | if(tid<0) 217 | { 218 | obj[1].attr2= -tid; 219 | obj[1].attr1 ^= ATTR1_HFLIP; 220 | } 221 | else 222 | obj[1].attr2= tid; 223 | 224 | 225 | // Set shadow 226 | obj_set_pos(&obj[2], 227 | pt.x + cLinkShadow[dir][0], 228 | pt.y + cLinkShadow[dir][1]); 229 | 230 | // Set head 231 | BFN_SET(obj[0].attr0, pt.y+cLinkHeadYs[sublut][frame], ATTR0_Y); 232 | 233 | obj[0].attr1 &= ~(ATTR1_HFLIP | ATTR1_X_MASK); 234 | obj[0].attr1 |= BFN_PREP(pt.x-cLinkShadow[dir][0], ATTR1_X); 235 | 236 | if(dir == LOOK_LEFT) 237 | obj[0].attr1 |= ATTR1_HFLIP; 238 | 239 | obj[0].attr2= cLinkHeadIds[sublut][frame]; 240 | } 241 | 242 | // EOF 243 | -------------------------------------------------------------------------------- /lab/bigmap/source/link.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sprite Link movement 3 | // 4 | //! \file link.h 5 | //! \author J Vijn 6 | //! \date 20070216 - 20070216 7 | // 8 | // === NOTES === 9 | 10 | 11 | #ifndef __LINK__ 12 | #define __LINK__ 13 | 14 | 15 | // === CONSTANTS ====================================================== 16 | 17 | enum ELookDir 18 | { 19 | LOOK_RIGHT= 0, LOOK_DOWN, LOOK_LEFT, LOOK_UP, 20 | }; 21 | 22 | #define SPR_STATE_STAND 0x0100 23 | #define SPR_STATE_WALK 0x0200 24 | 25 | // === CLASSES ======================================================== 26 | 27 | typedef struct TSprite 28 | { 29 | FIXED x, y; //!< Position 30 | FIXED vx, vy; //!< Velocity 31 | u16 state; //!< Sprite state 32 | u8 dir; //!< Look direction 33 | u8 objId; //!< Object index 34 | FIXED aniFrame; //!< Animation frame counter 35 | } TSprite; 36 | 37 | #endif // __LINK__ 38 | 39 | 40 | // -------------------------------------------------------------------- 41 | // PROTOTYPES 42 | // -------------------------------------------------------------------- 43 | 44 | void link_init(TSprite *link, FIXED x, FIXED y, int obj_id); 45 | void link_set_state(TSprite *link, u32 state); 46 | void link_input(TSprite *link); 47 | 48 | void link_move(TSprite *link); 49 | void link_animate(TSprite *link); 50 | 51 | 52 | 53 | // EOF 54 | -------------------------------------------------------------------------------- /lab/octtest/graphics/octants.grit: -------------------------------------------------------------------------------- 1 | # Affine tile map, 8 bpp, LZ77 compressed. 2 | -gt -gB8 -gzl -mRa -mLa -mzl -m -p 3 | -------------------------------------------------------------------------------- /lab/octtest/graphics/octants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/lab/octtest/graphics/octants.png -------------------------------------------------------------------------------- /lab/octtest/source/octtest.c: -------------------------------------------------------------------------------- 1 | // 2 | // Oct test: getting the octant from coordinates 3 | // 4 | //! \file octtest.c 5 | //! \author J Vijn 6 | //! \date 20061001 - 20061001 7 | // 8 | // === NOTES === 9 | 10 | #include 11 | #include 12 | 13 | #include "octants.h" 14 | 15 | 16 | #define OCT_STATE_ROT 1 17 | #define OCT_PAL_START 1 18 | 19 | void init_main() 20 | { 21 | int ii; 22 | 23 | // --- irq --- 24 | irq_init(NULL); 25 | IRQ_SET(VBLANK); 26 | 27 | // --- bg --- 28 | GRIT_CPY(pal_bg_mem, octantsPal); 29 | for(ii=0; ii<8; ii++) 30 | pal_bg_mem[ii+OCT_PAL_START]= CLR_GRAY; 31 | LZ77UnCompVram(octantsTiles, tile_mem[0]); 32 | LZ77UnCompVram(octantsMap, se_mem[30]); 33 | 34 | REG_BG2CNT= BG_CBB(0) | BG_SBB(30) | BG_AFF_32x32; 35 | REG_BG_AFFINE[2]= bg_aff_default; 36 | 37 | // --- obj --- 38 | const TILE dot= 39 | {{ 0, 0, 0x00011000, 0x00122100, 0x00122100, 0x00011000, 0, 0}}; 40 | tile_mem[4][1]= dot; 41 | pal_obj_mem[1]= CLR_LIME; 42 | pal_obj_mem[2]= CLR_GREEN; 43 | obj_set_attr(&oam_mem[0], ATTR0_SQUARE, ATTR1_SIZE_8, 1); 44 | 45 | // --- text ---- 46 | tte_init_chr4c_b4_default(0, BG_CBB(2)|BG_SBB(28)); 47 | tte_init_con(); 48 | tte_set_margins(8, 8, 232, 40); 49 | 50 | REG_DISPCNT= DCNT_MODE1 | DCNT_BG0 | DCNT_BG2 | DCNT_OBJ | DCNT_OBJ_1D; 51 | } 52 | 53 | int main() 54 | { 55 | init_main(); 56 | 57 | int x=12, y=8; // Coords, relative to center.of screen 58 | u32 state= 0, oct_curr= 0, oct_prev= 0; 59 | OBJ_ATTR *dot= &oam_mem[0]; 60 | 61 | AFF_SRC_EX asx= { 128<<8, 128<<8, 120, 80, 256, 256, 0}; 62 | bg_rotscale_ex(®_BG_AFFINE[2], &asx); 63 | pal_bg_mem[oct_curr+OCT_PAL_START]= CLR_SILVER; 64 | 65 | while(1) 66 | { 67 | VBlankIntrWait(); 68 | key_poll(); 69 | 70 | x += key_tri_horz(); 71 | y += key_tri_vert(); 72 | 73 | obj_set_pos(dot, x+120-4, y+80-4); 74 | 75 | oct_curr= (state&OCT_STATE_ROT ? octant_rot(x, y) : octant(x,y) ); 76 | 77 | if(oct_curr != oct_prev) 78 | { 79 | pal_bg_mem[oct_prev+OCT_PAL_START]= CLR_GRAY; 80 | pal_bg_mem[oct_curr+OCT_PAL_START]= CLR_SILVER; 81 | oct_prev= oct_curr; 82 | } 83 | 84 | if(key_hit(KEY_START)) 85 | { 86 | state ^= OCT_STATE_ROT; 87 | asx.alpha ^= 0x1000; // pi/8 88 | bg_rotscale_ex(®_BG_AFFINE[2], &asx); 89 | } 90 | 91 | tte_printf("#{es;P}(%d, %d) [%d]", x, y, oct_curr); 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /lab/octtest/turret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/lab/octtest/turret.png -------------------------------------------------------------------------------- /lab/prio_demo/graphics/ball.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Ball : 4bpp, not compressed. 3 | # 4 | -gB4 5 | -------------------------------------------------------------------------------- /lab/prio_demo/graphics/ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/lab/prio_demo/graphics/ball.png -------------------------------------------------------------------------------- /lab/prio_demo/graphics/cage.grit: -------------------------------------------------------------------------------- 1 | # 2 | # Cage : 64x64t, 8bpp, SBB-layout, not compressed. 3 | # 4 | -gt -gB8 -mR4 -mLs 5 | -------------------------------------------------------------------------------- /lab/prio_demo/graphics/cage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbadev-org/libtonc-examples/6fec3696d113a86c0ebae1c003861642c9215ee7/lab/prio_demo/graphics/cage.png -------------------------------------------------------------------------------- /lab/prio_demo/source/id_sort_shell2.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ id_sort_shell2: general shellsort unsing an index table 3 | @ MAXCOUNT: 256 4 | @ === NOTES: === 5 | @ * changed from oe->fill keys to int keys after completion; 6 | @ not fully optimised for that yet. 7 | 8 | .section .iwram,"ax",%progbits 9 | .align 2 10 | @ DECL: CODE_IN_IWRAM void id_sort_shell2(int keys[], u8 ids[], int count) 11 | @ r0: sort key (oe.fill) 12 | @ r1: sort indices 13 | @ r2: array length 14 | @ r3: inc 15 | @ r4, r5, r6: inc, ii, jj, jj-inc 16 | @ r7: id= ids[jj-inc] 17 | @ r8, r9: id0=ids[ii], key0=fill[ids[ii]] 18 | @ r10: fill[id] 19 | @ r12: (1<<32)/3 20 | .global id_sort_shell2 21 | id_sort_shell2: 22 | stmfd sp!, {r4-r10} 23 | @ TODO: special for count==1 24 | @ setup inc: inc= 3*inc+1 25 | mov r3, #0 26 | .Lshell_inc_setup: 27 | rsb r3, r3, r3, lsl #2 28 | add r3, r3, #1 29 | cmp r3, r2 30 | ble .Lshell_inc_setup 31 | ldr r12, .Lshell_pool 32 | @ inc loop 33 | .Lshell_inc_loop: 34 | umull r5, r4, r12, r3 @ ii= inc/3 35 | mov r3, r4 @ inc= ii 36 | cmp r3, r2 @ ii>count 37 | bgt .Lshell_up_loop_end 38 | @ ii=inc to nn loop 39 | .Lshell_up_loop: 40 | ldrb r8, [r1, r4] @ id0= ids[ii] 41 | ldr r9, [r0, r8, lsl #2] @ key0= fill[ids[ii]] 42 | mov r5, r4 @ jj= ii 43 | sub r6, r5, r3 @ jnext= jj-inc 44 | @ jj=ii to 0 loop 45 | .Lshell_down_loop: 46 | ldrb r7, [r1, r6] 47 | ldr r10, [r0, r7, lsl #2] 48 | cmp r10, r9 @ fill[id] > key0 49 | ble .Lshell_down_loop_end 50 | strb r7, [r1, r5] @ PONDER: xxxgt? 51 | mov r5, r6 52 | subs r6, r5, r3 53 | bge .Lshell_down_loop 54 | .Lshell_down_loop_end: 55 | strb r8, [r1, r5] @ TODO: clean 56 | add r4, r4, #1 @ TODO: combine with ldrb 57 | cmp r4, r2 58 | blt .Lshell_up_loop 59 | .Lshell_up_loop_end: 60 | cmp r3, #1 61 | bgt .Lshell_inc_loop 62 | ldmfd sp!, {r4-r10} 63 | bx lr 64 | .align 2 65 | .Lshell_pool: 66 | .word 1431655766 67 | 68 | -------------------------------------------------------------------------------- /lab/prio_demo/source/prio.iwram.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | //! Sort indices via shell sort 6 | /*! \param keys Array sort keys 7 | * \param ids Array of indices. After completion keys[ids[ii]] 8 | * will be sorted in ascending order. 9 | * \param count Number of entries. 10 | */ 11 | IWRAM_CODE void id_sort_shell(int keys[], u8 ids[], int count) 12 | { 13 | u32 ii, inc; 14 | 15 | // find initial 'inc' in sequence x[i+1] = 3*x[i]+1 ; x[1]=1 16 | for(inc=1; inc<=count; inc++) 17 | inc *= 3; 18 | // actual sort 19 | do 20 | { 21 | inc /= 3; 22 | for(ii=inc; ii=inc && keys[ids[jj-inc]]>key0; jj -= inc) 27 | ids[jj]= ids[jj-inc]; 28 | ids[jj]= id0; 29 | } 30 | } while(inc > 1); 31 | } 32 | -------------------------------------------------------------------------------- /lab/prio_demo/source/prio_demo.c: -------------------------------------------------------------------------------- 1 | // 2 | // prio_demo.c 3 | // Fun with priorities 4 | // 5 | // (20060223 - 20070809, cearn) 6 | // === NOTES === 7 | // * Almost done ... fixing controls 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include "ball.h" 14 | #include "cage.h" 15 | 16 | // -------------------------------------------------------------------- 17 | // TYPES 18 | // -------------------------------------------------------------------- 19 | 20 | 21 | typedef struct TSprite 22 | { 23 | VECTOR pos; // position 24 | int id; // oe-id in OAM buffer 25 | } TSprite; 26 | 27 | 28 | // -------------------------------------------------------------------- 29 | // CONSTANTS 30 | // -------------------------------------------------------------------- 31 | 32 | 33 | #define SPR_COUNT 96 34 | 35 | const VECTOR P_ORG= { 112<<8, 0<<8, 0<<8 }; 36 | #define AMP 0x3800 // amplitude (.8) 37 | #define WAVEN -0x002C // wave number (.12) 38 | #define OMEGA0 0x0200 // angular velocity (.8) 39 | 40 | #define S_AUTO 0x0001 41 | #define S_SORT 0x0002 42 | 43 | 44 | // -------------------------------------------------------------------- 45 | // GLOBALS 46 | // -------------------------------------------------------------------- 47 | 48 | 49 | TSprite sprites[SPR_COUNT]; // Sprite list 50 | u8 sort_ids[SPR_COUNT]; // Sorted OAM indices 51 | int sort_keys[SPR_COUNT]; // sort keys 52 | int g_phi= 0; // phase, integration of omega over time 53 | int g_omega= OMEGA0; // rotation velocity (.8) 54 | u32 g_state= S_AUTO | S_SORT; 55 | 56 | int g_time; // profiling 57 | 58 | OBJ_ATTR oam_buffer[SPR_COUNT]; 59 | 60 | 61 | // -------------------------------------------------------------------- 62 | // PROTOTYPES 63 | // -------------------------------------------------------------------- 64 | 65 | 66 | void init_main(); 67 | 68 | void spr_helix(const VECTOR *p0, int phi0); 69 | void spr_update(); 70 | 71 | IWRAM_CODE void id_sort_shell(int keys[], u8 ids[], int count); 72 | IWRAM_CODE void id_sort_shell2(int keys[], u8 ids[], int count); 73 | 74 | 75 | // -------------------------------------------------------------------- 76 | // FUNCTIONS 77 | // -------------------------------------------------------------------- 78 | 79 | 80 | // Helical pattern: 81 | // ft(t) = INT(w(t'), t', 0, t) 82 | // (x,y,z) = ( x0+A*cos(k*y+ft), y, A*sin(k*y+ft) ) 83 | void spr_helix(const VECTOR *p0, int phi0) 84 | { 85 | int ii, phi; 86 | VECTOR dp= {0, 0, 0}; 87 | TSprite *sprL= sprites, *sprR= &sprites[SPR_COUNT/2]; 88 | 89 | for(ii=0; ii>4) + (phi0); 93 | 94 | // red helix 95 | dp.x= AMP*lu_cos(phi)>>12; // .8f 96 | dp.z= AMP*lu_sin(phi)>>12; // .8f 97 | vec_add(&sprL[ii].pos, p0, &dp); 98 | 99 | // cyan helix 100 | dp.x= -dp.x; 101 | dp.z= -dp.z; 102 | vec_add(&sprR[ii].pos, p0, &dp); 103 | 104 | dp.y += 144*256/(SPR_COUNT/2); 105 | } 106 | } 107 | 108 | void spr_update() 109 | { 110 | int ii; 111 | int prio, zz; 112 | u32 attr2; 113 | int *key= sort_keys; 114 | TSprite *spr= sprites; 115 | OBJ_ATTR *obj; 116 | 117 | for(ii=0; iiid]; 120 | // set x/y pos 121 | obj_set_pos(obj, spr->pos.x>>8, spr->pos.y>>8); 122 | 123 | // set priority based on depth. 124 | attr2= obj->attr2 & ~(ATTR2_PRIO_MASK | ATTR2_PALBANK(1)); 125 | zz= spr->pos.z; 126 | if(zz>0) 127 | { 128 | prio= 2; 129 | attr2 |= ATTR2_PALBANK(1); 130 | } 131 | else 132 | prio= 1; 133 | obj->attr2= attr2 | ATTR2_PRIO(prio); 134 | 135 | // set sort key 136 | // key{1E-1F} : priority 137 | // key{00-1D} : depth value = -zz 138 | // Sort gives an ascending array, but key-signs mean the 139 | // following ranges 140 | // prio 0 : [E, 2> *1000:0000 = [-2,+2> 141 | // prio 3 : [A, E> *1000:0000 = [-6,-2> 142 | // to make prio 0 be lowest, subtract 6 (=8-E) 143 | *key++= (prio<<30) + (zz>>2) - (6<<28); 144 | 145 | /* // If you want to exclude hidden sprites, use this: 146 | if( (oe->attr0&OE_A0_MODE_MASK) != OE_A0_HIDE ) 147 | sort_keys[ii]= (prio<<30) + (zz>>2) - (6<<28); 148 | else 149 | sort_keys[ii]= (1<<31)-1; 150 | */ 151 | spr++; 152 | } 153 | 154 | profile_start(); 155 | if(g_state & S_SORT) 156 | { 157 | // sort 158 | id_sort_shell(sort_keys, sort_ids, SPR_COUNT); 159 | // try the asm version too some time 160 | //id_sort_shell2(sort_keys, sort_ids, SPR_COUNT); 161 | 162 | // update 163 | for(ii=0; ii 3 | #include 4 | 5 | int main() 6 | { 7 | // Init interrupts and VBlank irq. 8 | irq_init(NULL); 9 | irq_add(II_VBLANK, NULL); 10 | 11 | // Video mode 0, enable bg 0. 12 | REG_DISPCNT= DCNT_MODE0 | DCNT_BG0; 13 | 14 | // Init 4bpp vwf text on bg 0. 15 | tte_init_chr4c(0, // BG 0 16 | BG_CBB(0)|BG_SBB(31), // Charblock 0; screenblock 31 17 | 0xF000, // Screen-entry offset 18 | bytes2word(1,2,0,0), // Color attributes. 19 | CLR_YELLOW, // Yellow text 20 | &verdana9Font, // Verdana 9 font 21 | NULL // Use default chr4 renderer 22 | ); 23 | 24 | // Initialize use of stdio. 25 | tte_init_con(); 26 | 27 | // Printf something at 96,72 28 | tte_printf("#{P:96,72}Hello World!"); 29 | 30 | while(1) 31 | { 32 | VBlankIntrWait(); 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # libtonc examples 2 | 3 | The examples in this repository are the v1.4.2 examples of libtonc, updated to 4 | be able to build with the current libtonc distributed by devkitpro, and without 5 | the "toolbox" library that some examples used to have. 6 | 7 | The examples have been upgraded so that they convert their graphics at build 8 | time. The exception is example `cbb_demo`, as it does special handling with the 9 | converted data, and it can't easily be replicated by an automated process. 10 | 11 | To build any of the individual examples, go to its folder and type `make`. 12 | 13 | To build all examples at once, type `make` in the root of this repository. All 14 | examples will be copied to folder `bin`. 15 | -------------------------------------------------------------------------------- /tonc-code.txt: -------------------------------------------------------------------------------- 1 | 2 | _______________________________________________________ 3 | // \\ 4 | || TTTT q cc cc || 5 | || TT qq c c c c || 6 | || TT qq c c c c ddd || 7 | || TT ooo qqq cc cc ooo d ee || 8 | || TT o q c c c c o d e || 9 | || TT o q c c c c o ddd e || 10 | || TTTTTTTTT ooo q c cccc c cccc ooo d d e || 11 | || || 12 | || || 13 | || || 14 | ||=========================================================|| 15 | || || 16 | || Tonc code: tonc projects and tonclib || 17 | || v1.4.2 || 18 | || 2003-10-01 - 2013-03-24, J Vijn || 19 | || || 20 | \\_______________________________________________________// 21 | 22 | 23 | // === Description === 24 | Tonc is a tutorial for learning how to program for the GameBoy Advance 25 | (GBA). It covers most aspects of the GBA, often in great detail and 26 | from an efficiency orientated viewpoint. Among other things, you'll 27 | see all video modes (0-6), sprites, simple and advanced button 28 | handling, Rotation/Scaling for backgrounds and sprites (covered the 29 | _right_ way for a change), mode 7 and programming in ARM assembly. 30 | 31 | Tonc consists of 3 parts: text, code and binaries. Tonc is part of 32 | http://www.coranac.com/ where you can find the on-line text, as 33 | well as zips for the three parts. This readme belongs to the code 34 | part of the set. 35 | 36 | NOTE: this is still a only a beta, though should be close to the 37 | final version. 38 | 39 | // === Tonc code (tonc-code.zip) --- 40 | This contains all the demo projects for tonc as well as the utility 41 | code library tonclib. The code is mainly meant for devkitPro r19 42 | and higher; for earlier versions or other devkits you'd need to make 43 | some adjustments. 44 | The projects fall into 4 categories: basic, extended, advanced and 45 | lab. The first three are ordered according to difficulty. The basic 46 | projects are fairly simple; they're completely self-contained using 47 | simple makefiles. The extended projects start to use tonclib and 48 | contail more advanced (but also more useful) makefiles. The advanced 49 | projects use tonclib even more, use assembly for data and yet more 50 | complex makefiles, derived from DKP's templates. The lab demos might 51 | fall into this category as well, except that they might not be 52 | completely finished yet. Still worth looking at though. 53 | Tonclib contains a good number of utility code, taking care of simple 54 | and not so simple items. There's types and a complete memory map + 55 | bit definitions in tonc_memmap.h and tonc_memdef.h. It contains a 56 | BIOS routines plus some extra, safe and safe memcpy and memset versions 57 | for words and halfwords and an interrupt system that allows for 58 | easy to use prioritized and nested interrupts. As this is a bit much 59 | to take in at once, there's also a doxygen generated manual in 60 | CHM format. 61 | 62 | // === Usage === 63 | Each project has a Makefile and a .pnproj file for for easy 64 | compilation. There are also Visual C++ 6 and Express projects for use 65 | with thise IDEs. You can also run things for a DOS/msys-box like this: 66 | 67 | `make tonclib' To build tonclib.a 68 | `make DEMO=foo' To build the `foo' demo 69 | `make DEMO=foo clean' To clean the `foo' demo 70 | `make build_all' To build all demos 71 | `make clean_all' To clean all demos 72 | 73 | // === Recent changes === 74 | 75 | - 2013-03-24, jv: 76 | + made ready for DKA r41 (uses arm-none-eabi iso arm-eabi-) 77 | - older 78 | Too many to list here. Look at log.htm in the text. 79 | 80 | // === Contact Info === 81 | 82 | J.Vijn 83 | cearn@coranac.com 84 | http://www.coranac.com 85 | 86 | 87 | --------------------------------------------------------------------------------