From 659ab34aee5a797b0c2bf6b46d69979032964336 Mon Sep 17 00:00:00 2001 From: iProgramInCpp Date: Sat, 19 Dec 2020 09:39:41 +0200 Subject: [PATCH] Add files to the repo --- LICENSE.txt | 21 + Makefile | 194 ++++++ README.md | 18 +- build.bat | 8 + build.sh | 5 + clean.bat | 7 + clean.sh | 2 + data/bmpfont.png | Bin 0 -> 941 bytes data/character.png | Bin 0 -> 1477 bytes data/clapperboard.png | Bin 0 -> 362 bytes data/copy_mode.png | Bin 0 -> 258 bytes data/dialog_bg.png | Bin 0 -> 1574 bytes data/dialogbtn.png | Bin 0 -> 567 bytes data/erase.png | Bin 0 -> 699 bytes data/erase_mode.png | Bin 0 -> 259 bytes data/item.png | Bin 0 -> 235 bytes data/itemsel.png | Bin 0 -> 230 bytes data/logo.png | Bin 0 -> 957 bytes data/lr_arrows.png | Bin 0 -> 274 bytes data/reset.png | Bin 0 -> 754 bytes data/tiles.png | Bin 0 -> 3326 bytes data/undo.png | Bin 0 -> 1044 bytes data/zombie.png | Bin 0 -> 1496 bytes run.bat | 2 + source/Enemy.cpp | 232 +++++++ source/Enemy.hpp | 31 + source/Engine.h | 674 +++++++++++++++++++ source/EngineDec.h | 110 ++++ source/Features/RNG.h | 22 + source/Font.h | 77 +++ source/Levels.inc.h | 34 + source/Main.cpp | 80 +++ source/Map.h | 31 + source/TestGame.cpp | 1427 +++++++++++++++++++++++++++++++++++++++++ source/TestGame.hpp | 49 ++ source/Typeface.h | 259 ++++++++ source/Utils.cpp | 20 + source/Utils.hpp | 11 + 38 files changed, 3312 insertions(+), 2 deletions(-) create mode 100644 LICENSE.txt create mode 100644 Makefile create mode 100644 build.bat create mode 100644 build.sh create mode 100644 clean.bat create mode 100644 clean.sh create mode 100644 data/bmpfont.png create mode 100644 data/character.png create mode 100644 data/clapperboard.png create mode 100644 data/copy_mode.png create mode 100644 data/dialog_bg.png create mode 100644 data/dialogbtn.png create mode 100644 data/erase.png create mode 100644 data/erase_mode.png create mode 100644 data/item.png create mode 100644 data/itemsel.png create mode 100644 data/logo.png create mode 100644 data/lr_arrows.png create mode 100644 data/reset.png create mode 100644 data/tiles.png create mode 100644 data/undo.png create mode 100644 data/zombie.png create mode 100644 run.bat create mode 100644 source/Enemy.cpp create mode 100644 source/Enemy.hpp create mode 100644 source/Engine.h create mode 100644 source/EngineDec.h create mode 100644 source/Features/RNG.h create mode 100644 source/Font.h create mode 100644 source/Levels.inc.h create mode 100644 source/Main.cpp create mode 100644 source/Map.h create mode 100644 source/TestGame.cpp create mode 100644 source/TestGame.hpp create mode 100644 source/Typeface.h create mode 100644 source/Utils.cpp create mode 100644 source/Utils.hpp diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..91f29a1 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2019 iProgramInCpp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..782e2db --- /dev/null +++ b/Makefile @@ -0,0 +1,194 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +.SECONDARY: + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro) +endif + +include $(DEVKITARM)/base_rules + +PORTLIBS := $(PORTLIBS_PATH)/nds $(PORTLIBS_PATH)/armv5te + +LIBNDS := $(DEVKITPRO)/libnds + +ifeq ($(strip $(GAME_TITLE)),) +GAME_TITLE := game +endif + +ifeq ($(strip $(GAME_SUBTITLE1)),) +GAME_SUBTITLE1 := test +endif + +ifeq ($(strip $(GAME_SUBTITLE2)),) +GAME_SUBTITLE2 := Made by iProgramInCpp +endif + +ifeq ($(strip $(GAME_ICON)),) +GAME_ICON := $(DEVKITPRO)/libnds/icon.bmp +endif + +ifneq ($(strip $(NITRO_FILES)),) +_ADDFILES := -d $(NITRO_FILES) +endif + +#--------------------------------------------------------------------------------- +%.nds: %.arm9 + $(SILENTCMD)ndstool -c $@ -9 $< -b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1);$(GAME_SUBTITLE2)" $(_ADDFILES) + @echo built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +%.nds: %.elf + ndstool -c $@ -9 $< -b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1);$(GAME_SUBTITLE2)" $(_ADDFILES) -h 0x200 + $(SILENTMSG) built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +%.arm9: %.elf + $(SILENTCMD)$(OBJCOPY) -O binary $< $@ + $(SILENTMSG) built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +%.arm7: %.elf + $(SILENTCMD)$(OBJCOPY) -O binary $< $@ + $(SILENTMSG) built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +%.elf: + $(SILENTMSG) linking $(notdir $@) + $(SILENTCMD)$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ + + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := source +DATA := +INCLUDES := include +GRAPHICS := data + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork + +CFLAGS := -g -Wall -O2\ + -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ + -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM9 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=c++14 + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lfat -lnds9 + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBNDS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ + $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(PNGFILES:.png=.o) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).nds $(TARGET).ds.gba + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).nds : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + + +#--------------------------------------------------------------------------------- +%.s %.h : %.png %.grit +#--------------------------------------------------------------------------------- + grit $< -fts -o$* + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/README.md b/README.md index cc1f568..9a1bc45 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ -# DSPlatformMaker -Platformer game maker for the Nintendo DS. +# DSGameEngine +A DS game engine based off libnds with frame buffer capabilities for the top screen. + +It includes basic image drawing functions with transparency and flipping, and basic rectangle drawing. + +The graphics work is all done in software, only that the CPU will copy the framebuffer data to the GPU of the Nintendo DS. + +It's quite inefficient, but who needs backgrounds and sprites when you can have this? + + +This repo will also have examples of programs written based off it. + +The platform game contains sprites from New Super Mario Bros. for the Nintendo DS. I won't provide them here for legal reasons. +The 3D engine doesn't contain any other things. + +You need devkitPro (namely devkitARM) to build. diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..c0a4b19 --- /dev/null +++ b/build.bat @@ -0,0 +1,8 @@ +@echo off +cd C:\Users\iProgramInCpp\Desktop\game +rem set DEVKITARM=C:\devkitPro\devkitARM +rem set DEVKITPRO=C:\devkitPro +rem set PATH=C:\devkitPro\msys2 +rem msys2_shell.bat C:\Users\iProgramInCpp\Desktop\game\build.sh +make +pause \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..39ecd9b --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +cd /home/iProgramInCpp/Desktop/game +export DEVKITPRO=C:/Devkitpro/ +export DEVKITARM=C:/Devkitpro/Devkitarm +make +read -p "Press [Enter] key to start backup..." \ No newline at end of file diff --git a/clean.bat b/clean.bat new file mode 100644 index 0000000..2869d56 --- /dev/null +++ b/clean.bat @@ -0,0 +1,7 @@ +@echo off +rem cd C:\Users\Myria\Desktop\DSGAME +rem set DEVKITARM=C:\devkitPro\devkitARM +rem set DEVKITPRO=C:\devkitPro +rem set PATH=C:\devkitPro\msys2 +rem msys2_shell.bat C:\Users\Myria\Desktop\DSGAME\clean.sh +make clean \ No newline at end of file diff --git a/clean.sh b/clean.sh new file mode 100644 index 0000000..a2eb20e --- /dev/null +++ b/clean.sh @@ -0,0 +1,2 @@ +cd /home/Myria/Desktop/DSGAME +clean \ No newline at end of file diff --git a/data/bmpfont.png b/data/bmpfont.png new file mode 100644 index 0000000000000000000000000000000000000000..edd104862df85f40db4e074212a6cfb6aa8e146d GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0y~yU;#22I9Qm0E$f&h%9Dc;5!7ujG`J|4Gav- zY@RNTArXhqhI0qKHsH}Y%sTG^>jLu|AOF7pw&?2h+*7m7FE8Xsc1p6|RJOH9PifKV zS+ipg=v`~_xPOH;e^2-0^p$_L?KU2tC+Tu^R>6*2ufDmTSKGz>aMCR4eup70x_ieA=rXZlk61OR9 zFN21=Yd!P)>fnOQ{2ymOTYG2QZ_y)dzo+eJ4Q5I>{AWMs1HCAdi&N@mN-{dEjxoM6 zj@$o;L0iehl8*Z&ZAWx4wAD#n=i0;K!>aL?BlTL(gx>;O!lf*GlpjxZ-EcJV zbx*>b2+exC`i&DAq@JvKR{dv39M?O?hA@U}EYU{;nUk910+^U2+qn#4A6VLoEbvok z*;~}V#z8GIw0R*z=Mh~-uZP}@Li-e)yIB@Gh8-wb!>Mp5f8G1pv*tt=h4n1qeD?bJ z?OiM<)+;u=^)^nt?0oq9XWjk?wni=Qh9i;(dP2?l{3I@C`Z7el*g1)1(|pEB482`0 z`w|2em{fjR_2Ae|NrpA|`J3sp1LjEU1LL*}tuW}Vv0@OjB! zCFyuZjip=JpWU7><2uj!#8%UAhPkD0Z*QKkd`88?34gT@{I;pPzVW`Q5?6qgn55J# znTRv%8B)$|%5uNuzopr0M?S48UO$Q literal 0 HcmV?d00001 diff --git a/data/character.png b/data/character.png new file mode 100644 index 0000000000000000000000000000000000000000..2c517af01f1902f964cc6257e944fd940cb6d12e GIT binary patch literal 1477 zcmeAS@N?(olHy`uVBq!ia0vp^4L~fw!3-o{wzcm9QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn~YUU}gyL32_w{7ncwau$2{JuuikDGGOqk_fZiGRFjC*l1kQ>%{EeCh@8og zwmx`)L)MwV{|x`ntnPbyV8Q=un}7z6g3%Bd>LFl1ExrNh2hIYI$YKTtzWpG~Xu%q+ z!oa}f=jq}Y;^Eyp>F%P%3Op^*OCxr#ZhHTJ!*5?9f$DQd&$-S%c|L_f-u>_a;RS0 z|5+oC!Rl3a(7s>$h18?Ch2JXqSzh{6Fo#bvg6lEQ*I!XL`ycF_{p`Dw{{I*KM?5)Z zMC2^;dgl1^&S`z~DoKWEjCv=YY>WRAwZkj+>4WbqbNwGJt((=Dn=Zi|ZESFF1<(}X zo=CPAj2533OYhK+>9L!C_kiueZA`C%x-v8+1Oh&vdF%F9d5LU9#s{9ns_-2)P4Cf=VGv}$Y4Nny`V z({KHCOFgj6(SwaSxBXDA{bNtzroL}lA-rxiacn^nFS;D_&AS@)Zt!kDGVgwY-1!Hu zzr2AmJ0}eH*md*_B7hKMDu`{oFRWqGYM#1Q~ljMbenl};@oPS#R z?H1sEqimD2?d;`m*O-n99Xub9d#6o}Q%XVa{fyF>v_3IBWsH-sBS^ebg z+4v)(W?fMTg`5qV)i7jim^L-Ypg4b~dzWZ5al8a>7-l)1YSDQap;hkJ;<1)q~r3-E03vv}a z8z$aQn~;J{?vOh=8_2i}}slz2A3f RFT4y21y5H$mvv4FO#n^-c-; zV~EE2t^Egi4;XMTa|%!4)%hmBY1vPP&Rcd-i){k38$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&di49pAxJ|V6^aVADa76ukh4pw0yZZSbVV?#Mhb0r&dRVxc67e|eR7|X<1 zt2pLQlww`K7zo6dv7Ed~$Ea?JMQC zuU7u}Q2X;^{f6x=JMTW<@$lK+7Z1*Dneb@$@(Zh;eRw(L=f{R$pBjIEZT<7L<^T8I z|KIyQe4O#|!>o^=XMXrR>;Lx&|9=3{r2juA|NlAn|Ic~;M1W{{Q#x|GzK)|Nr>^|L6bzzyAOK`~UyH|Ns9317sA8 zoDe7$brPzS2}P}p{9KMe0$?pNBzugstWc@ zU}-R^xwkF+f5g^nee3)d~ZTrGKJL==rvrp?8mhZY<0xBrb!Ghhs=t5xri#%bh z;=69MU=we6X9g;JFaSM`-^Q@^KSSo9oY#55*88ktyBOS?Kis@~P2cC%%QkoZK5-=n zQ~vviK&+qL%@BRl;7`I0gX+HuOn=si@0t;MC0tGUz~j4HG)j$E>0Fu~EG(!{`DN#{ zr{-b**$>aQS-p4G&e=T-liKs`-^!cKax>-oe&1#$*L!(pmG8^apNmiLjhZum?z}l3 zldPEx^cZHaH(WDg*s_gr!B$>|wYdx#xy%mP(hO0z87|ynqq5Yju$6yUBZNF}t#wzw P3W^6$S3j3^P6anMpoTM^E{-7?&TnsR>^kHi!1f^J>LHG-)hl)LO&>MomI>PWM?c%#|1Nv{;J?$ie@lm%7%&_*`1JEncAp(*l7$T4 z_S?MGzZed69{$pORLNid09%08R5?p7Mr;3t0SEdHy0q+w(X;=qq@*kvzwUO)Y7gZ@&H-bN%Q%9{D}{H|18F%}#V~W8RUz z{dS@&kZxzLsFP_(A_gf{vNj(LTP+%Pq~&=f(Bz{@jiQEycJrGR4)nP``~0(L=aIIE z9jvnb?r&x+i(P-+Z@Kboucb=dRu2{5Sez@dvYqQ!^m6Lj>#yAw3*Mhz>%dT9ex>wo z-uByBTVH*x+8HzL{k%!Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940#HdrK~zXf-ImX5 z6G0TmXO|o{u(T7YuqiF=LJk%x2p*c$OE0~6^58$?KcIhv=s)1EoVfkHijq8@ zO4TBiaXNEHTMR?c{(VkXRv3bIaeejR-2r+345T1P&KR4!%k|TC zCaH!9q##KC7+I#pwbfT|UMqhZEM5Id03whgX98_FhqYRvz#lxkuUZ$N`l2fO;ZAu6 zcFd`wT&Wy4zgJ(rRqniC;K|vUQa89<$-9*@Vmy2Le6D<;GlpPbrF@T?qC^f}V$gqI zJA`p}`_|t6o@z`0HS^)T=Raw*dOX`AV#3V5m*2K002ovPDHLkV1j#yJ1zhK literal 0 HcmV?d00001 diff --git a/data/erase_mode.png b/data/erase_mode.png new file mode 100644 index 0000000000000000000000000000000000000000..449e4a9fd41879c489839b82464485b9b6355d73 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^4nQox!VDxsPNql!DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe1_3@Ht_*7b|1?cLN|yit literal 0 HcmV?d00001 diff --git a/data/item.png b/data/item.png new file mode 100644 index 0000000000000000000000000000000000000000..ee11b3efc56f70e26c9251e60b3d828ebcd09eba GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-A0X`wFQIXT*Vy6`sZvW5lfBpJ%+c%%zy6yblUHA9yyZ8S6_wS#-|Ns3T zs1^!lvI6-A0X`wFrY3Hd7GCb|(eCc?{=UV2{y2Tn|5*GHX1V&{?ivTum4Z{PC zmsT(sGD$dgh@4oJz}S=V!hz`t*BKXP749>0I2pWJChEP@y%`Cz($m$?Wt~$(696w* BJZ%5~ literal 0 HcmV?d00001 diff --git a/data/logo.png b/data/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8fa24b5c0503ec79fc555bbff30a19b10c609bc7 GIT binary patch literal 957 zcmV;u148_XP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D15!yuK~#8N?VHPz z;~)%0)4iKb|NnQ+W|kSNW5qWr0m25qxJOkT2LyTmiW66VJs;2KW8!NPkEwsYT1e?C z-WVh|J~vj!MdwfHS^Fiul09TiY&gc#@%+fyQEL1aqVbmWO7RG}IlMlcGewPl%CFJ* zmOr^GT$0|HF)#4ve_cG-tkAs`A{2UZ9IF$zn7h}BUyNtLR%FvNnUmJs%UDA zkn0no{azoE((~re*^Jr~a`OlgI|%A{e$@CD#rje5GuJPD_C4bHU#p)Zr=PPk8oze{ zf|rOj$w`fgBpusPzXd7#Eo`=mt!MmeKp#r}csZzv#~a^^-t%9HcL7Kt$!eLf(p~T1G_>aXc0I!<=DIVC5 zLbek<448M7R-g~P59gM6MN*&+%FN&Sby&LH0i3m(<0e2kBWK8=_;A*>+{zT!&wM#7 zZUN9m7s-KoD#~=I{>_(NIr9N-0p`?W$^0TmqU(VYA*zRQqNG3_6(wr(&NRORfCT@U zU%P<|I9-Qs=ay~oDdZS1_j?^kuJ^)ae*|a|`g+<^P-UYx*ddr1~EHJjCehSoy==Y*WY$FoMBWcUGO*)FwYQyGii6{|! zo=z)2E$AZ((lWLh(1w*OQpyj;XNA=Bdk2t9dg~2anlEB+Pk(D@5gTEi_T>HVz=V+T zxa?B^LdbSl00TZ@-pa&2z?8-Q&7*JsyD>|sc?dqnhfKC3J5@l}cXr=tCKoCs2y zH-e5sA@}3*1wc3EmQ5;~JwjBk2K8H{$NXCme^A6naxX4l0Ayq8t6pCT_4|sxlk0Qq zuK;8{{Inl~TNeQNRMp#Skt084)fdG2ClaAFt|o5O6H#5yMs6N*P59q{gbWP70uVAV fEC7TI%j5AM?xMM}bsQ7`00000NkvXXu0mjfGQPVN literal 0 HcmV?d00001 diff --git a/data/lr_arrows.png b/data/lr_arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..0e93dbdeae78541269429f96565fa813490ad626 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-A0X`wF{~7+bG__5gJZLi-tzF4hOavhE*&_ay~M2JA^c_ z`dnbKnqzx`MZxO>=Ys5m1|mmqaqKu8rO5QEpi!xVLDPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940*6UNK~zXf-ImX8 z(?Af$H^xE^vZzagEuT9n{|8qq<2EDgq%R5?*Lr2lXq-er4Dq4VHj)} zX^KQKk-#w1Yk6BPh!PBT@-{Au{3*^7K;2oh$(a-Xvdril)C1fmE<}XN<+3nBlu9MC zVyJ)WdZW(EJzz+HV=x$wab1@z2?QhKG7u4JLpB^Aeu*$=lGGh{5O;F|h(L;*06&30 zBa@-bF)gL}6F@m5B@{Vyf1;B;LdRMqQ-!PxJFe$pLAkvGWi!EyF}|SOT~aA0*&CPG(|K8P|O{#F_j_LV{Yo)g^N-mZH@`NKk7W#Xix_M@Ufn^NTDcsEIhp zkBWehpq5=--hI7Go)T0>93eXZQV=9(gl?G&wY`JQ9=D`@Dt5Q|7RW(&YzLsd^`my7 zm?K|+?fccvo5zoy&`M7LTPm>|{+av$h(Idhd5~MpY0RiR+Yu?xN9AedQtAq%$Pb`} zRwx!fH^0o0W3oQ@`2-ama?ty$*f2lwvF{g@5v{`}<&-v4>0SU@{P zF!seuFmn#bXS2ofdCcjG~1_~%bB3NU|CpAa!o=^ kB*0W9^J2K*=K*7X0jWXEmA~(A-T(jq07*qoM6N<$f{zST%K!iX literal 0 HcmV?d00001 diff --git a/data/tiles.png b/data/tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f6d0504eb6ebc0987b00b8e5a03358bd4584d3 GIT binary patch literal 3326 zcmeHJ`8(A67k_`oj2UY)qU?qyTQqXXmS!;aeJivWOGtIm@+I4RkZVab!ibcqs8HFm zX1yde)W}VW%P65M#!h8szWVL^eE)`f&U0SpIj`sSoF87#`Qc=^x!6jG%8LR3B<$@d z9$Ov$RT!ZyT;XJY-)hh~4_iy{@MTotlgjVTY?8&Rt#BS6iM2KoC(W)^yhq8c6Ul zpoIf6nM|cpV`F21ZvhCY1hf&*2*3~s&juGuLHuLjUgYk{B!~C8gIocrQjn0HkpV!d zicV^{d)DtBeE_`HFcJVDAX;uo1mR!-EC_(0CL7e#!?U_Uy#S>DbF8l%e0c_5-@Pap z27<3N7>3i*(ijXzQBe`&{>`eE$5mBTeHB+ZT@Su=FnfA>1_lO(hle>F&ceciK(Mv` z-}u*o|98L$jsJBSB9V5!=Kzpw|5cDN%9F6grP)&~ykd^e6(;yg8%d`I)v?Rix)s*P z^6K}d`y4Cx%&qqlT}3@w=C!-LXHE3Y@q60x$gLLo=(5xGf~?wRv$CPH`I@AI zj^~Srw$IxcQPDjaLq#W?=5-%SAg16Hs_dGIT#gQfXX30#Xp?oAJy+==532 zjuVOf`%vB>TKc43XO0GApRObjjF*ufb|PKdcxwu*@<7;7F8)>$1llv&5u4Q%FbHe8 zAy8PsJ8xRpd!sUe^$?7s@YB*NDh^C4iFdNk=3PjK`~3b|_cs>}uG(f2(twhNG{{O=RjR`OEByM~57AD}(L+8uCS#~?+> zmzWKK!-e!!USGQ@BJEm(GAs15N^hYAGORGUw-`A@>@99phTO6ZPoaG(9@Z<}tSj4s z2=;p!-`fAc{@$wn0*B!KrMa&LH~kWC*aSK2((Px}-T{8inVzQ^`$t9w&uEYQZe=V; z?%JvB^?4C<{j^mJMFQ0PedhGS%y58dszBPR>eh*&it^=UqW?mj6pxh9ylB6)8dG+< z+)-;$m{8zsPICbsw^A)*8Cov<`2A)iQp4Msu7}uaIL43ZXM>kRLBqq5E+T*&x-knK z6Fpk+Ei+eSPE{%l2cBn%0*~Y=1f6IaxwKEj0VY87+_eQX-FofEQP0~NY3Um z2fD96(@cqlCP(kN>w#s`$L_ip)oJFVwThQJwzazML)^{T&cM?%CpcQzpkfBN{(ELb z2;XiN)L@e1ZnF%$A<8m{lySRhl7?sXoE4+9swBbkk~*EXQF65z6Kl&X*FzNgp-=l3 zzKjajV|eENRqndE8xQW&tITyf3C%2|8nV4 zKjovtZNE+IQ*g;-LsUDbCnmdSG+6Bmcl(#S1dogRwcO2 z!Vq4kX~eRnZtGu8grm7*873#%EaoNWmx4@}51A>4as`RhF?LERXn7XRJ&xBK#~;WI zxp6$EG6^&}$|a?D#HVa}?$ex%)B^jGz6-xoW)V?%wJjMa;iC7VnFPIYCZIO!z+`Hh zgc=bd&0CQ1ur)85Eq;gv%zNO+jWw{FbE z&3w%IR!4T@<8g&Y74bXby3fvkesO?5^)q8>(_L+Ls5C9xCsEE`o{&7fJozlb**Wf- zPVUL%gE{ys)jPZ2cBN%zBImwVK1fC`mRRYmFPdcCe2v7H;WALSYjL)6{n{!Ig209z?E%51^W%iS5D*$`0qd>@G1S}gTfpD7z zbmB^Lu&%Yv5kj_sT?q(k^DFKrxCVHB8l!v|jCM=hxlLtlGQgEEG-{gu)QP3&Z1$jjr^=tkExL^Jc5kV>eaY+3_Ay!^78T;)fhv!#*ED+kWY7l^KtIdvc_VWx0*F9+0uh-HXVEe~=zR(U@8~ zZ9V0@Ua}mdT`tskctjBnnN9K3ubmz$9h-)&UK7Zfu8h*e40>EQhs34NG?-GuV>VX$UcVwIIrvZyP2^LKsIRp&Jp=awK9%^ zsY4>;obko=>CVoipPL19XuupasAVsR^P4e|OHnPEB~xC!YRQsU_CHhnSBic>YzJt# zNKAFD@_B__xr;`FmJqr00^O1b-~41C(jhJ)4d*8VuTS2Dyk~%8mPk{ziyObU4b&Ix zf`f;ZwpY&TEk>xaO%vKHi5t`CUTT)mrcB3Pr&evB0rUdzhpGRg*;9$HcxrFg5`am3 zYo7(N?`%&_j7)XSQnJb?kqv$;2s^V@YW3k5VM3mFMl|rlHlBLLH@cz0YW|*bXoc79 z;a!*D|DhRW2zo0Wu{o+BtXFF~A~1|gE0Ib)8`m<0V_SERGI5%s^QnY|(9?gkjp8bC zQuE`>YLkB} zJkt>JyHFtyoi|zmw-)80t51c_r2x(ol?Y67816qkr<9=&Z6zF>oOna>V;rj;Yf7{a~KqfNLA&rboe*;?qOI}L%A^+%#?Tc!-%!Z{e^2MqGvt0CQo z!t{~<@dg2eHSEgObUkjn@>L?#DUD$lT_!RIC|{%I2&D3-c_Sl7LaGelBGgYmvWdb= z1BF8)Xk83vou8GoF$R^LvPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ941F1TC zk*0`Y6jBEzgkcyQ2n0n>F0vK~go2Gth8hsg_BNcQg&*RAjUEmLN16<{CE6aG5J5fC zXmDEvTJZ_GeutLVM9+Z=dj5!74wI(1H$AhIPKm7K2obi))xV6>>C1HX3Ud>1^=lmz z|3(?xYusV8o(X3k0Mm2EN-Pkr6TZV!rj=o~R3Dw9=0nuiNgsOH9X5K@J#nN+76?%y zv2N{9d)_kItf3KWYs(rQvrb&H_8nt)*qIC)fIHq|3?IfjC6I!kMV7qS4p>FnAc4TI zu_z}un2+4|7f+ms;~uW2a1|v@x_Q^V2`MGfSOM4-iGX0V40K|JHC^f)EZ_BjDs_9j z9ZZK3R_MaE(QsC|h0*W`eqrX=By%5ls|BEmHL%f~NI{N;qiqHX^YR?A&l51wqlU(ezN+^vt3=Gyebrh_49p-)(=F07M`KLHoUcg*jYT^XkoO-YyEB zIhiepK+1mOz}_^}H)s^-ec8vmc1Leduiv*HQlhV>>&-2vB6WtY{3B$gGQTt$|D0H18?6YHBE0;Sr0`G2*}2)o{32f_ zACN}Pc(V!$FTg>>5_5|irm3z3-7;OrX>!%OO4b7S9tm@AaH?oeAo>H8vJTNn~YUU}gyL32_w{7ncwau$2{JuuikDGGOqk_fZk^HxLX|lZe!kO4gUnHd3gK zFky(C$&j`_c!5LKnZVkKot+E}|3T>gv}Ln5>{PLAJCa!Q5shBfCt-uSw= z-n_=o;q~XgW_;7cAAICASnx3@?`W{;#kH0v4|wjMrvKM;qtoir4SEGfDtDg~jQzK< zkf(C5+OAFKuGqZ%zx}?jwvz*2-2v`Yt0~tl|0XZKd*1eOmDv)X$q~zcF1ioY{^Z3T z#b?nP9%sidN&zqraLWB<| z8^?;JEx!sE{}Nx&Da*ymd%%h(<_qH~=5q{k9632g6CN-Luj_jq*voleU`rmg#W0!P|=Yl_byd%BxeoIR#9v zoM#AiJn}44;lhDwj1u$BxtM1!_};!!?b#2OC+m%Se z-Hj7}1oN&@zCF>9`Qyq>tDoz*Ma-Oe;OiUR6}*PuwlPR;s51|Ee_GOb0vpePhWb>) zCWakM>PabgBod~6zs-Aq(S^-^0$WAh`!$9Fjvq_cM0GILwnT0&mCN;)J1|4(!{rd| z>jD0bj7OgEI^X|pF!8MO)<^sQSn>R6$vEIveOn+hcHV-OZhLJrnA?BdeW^>bP0l+XkK D;ssMN literal 0 HcmV?d00001 diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..d3ffc89 --- /dev/null +++ b/run.bat @@ -0,0 +1,2 @@ +cd desmume +desmume.exe ..\DSGAME.nds \ No newline at end of file diff --git a/source/Enemy.cpp b/source/Enemy.cpp new file mode 100644 index 0000000..803d281 --- /dev/null +++ b/source/Enemy.cpp @@ -0,0 +1,232 @@ +#include "Enemy.hpp" + + +#include "zombie.h" + +glImage* mushroomImage; +glImage zombieImage[8]; +short zombieBmp[128*16]; +int zombSpriteID; + +Enemy::Enemy() { + +} +Enemy::~Enemy() { + +} + +void Enemy::Update (float fElapsedTime) { + if (this->posY > nLevelHeight) return; + if (this->posX > nLevelWidth) return; + if (this->posX < 0) return; + if (this->markForRemoval) return; + switch (type) { + case Enemy_Mushroom: + case Enemy_LifeUp: { + if (mushroom.risingTimer > 0.0f) { + if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) { + mushroom.risingTimer -= fElapsedTime; + posY -= fElapsedTime; + if (mushroom.risingTimer <= 0.0f) { + mushroom.risingTimer = 0.0f; + } + } + velX = 5; + } else { + // gravity + velY += 20.0f * fElapsedTime; + isOnGround = false; + for (int i = 0; i < 5; i++) { + float newX = posX + fElapsedTime * velX * .2f; + float newY = posY + fElapsedTime * velY * .2f; + + if (velX < 0) { + if (IsSolid(GetTile(newX + 0.0f, posY + 0.0f), DIR_LEFT) || + IsSolid(GetTile(newX + 0.0f, posY + 0.9f), DIR_LEFT)) { + velX = -velX; + newX = (int)newX + 1; + } + } else if (velX > 0) { + if (IsSolid(GetTile(newX + 1.0f, posY + 0.0f), DIR_RIGHT) || + IsSolid(GetTile(newX + 1.0f, posY + 0.9f), DIR_RIGHT)) { + velX = -velX; + newX = (int)newX; + } + } + if (velY < 0) { + // no triggering blocks + if (IsSolid(GetTile(newX + 0.0f, newY), DIR_UP) || + IsSolid(GetTile(newX + 0.9f, newY), DIR_UP)) { + velY = 0; + newY = (int)newY + 1; + } + } + if (velY > 0) { + if (IsSolid(GetTile(newX + 0.0f, newY + 1.0f), DIR_DOWN) || + IsSolid(GetTile(newX + 0.9f, newY + 1.0f), DIR_DOWN)) { + velY = 0; + newY = (int)newY; + } + } + posX = newX; posY = newY; + } + if (isOnGround) { + if (velX == 0) velX = 5; + } + Rectangle ri = { (int)(posX * 100), (int)(posY * 100), 100, 100}; + Rectangle rp = { (int)(fPlayerPosX * 100 + 20), (int)(fPlayerPosY * 100), 100, 80 }; + if (RectangleIntersect(ri, rp)) { + if (type == Enemy_LifeUp) + IncreaseMaxHP(); + else + HealPlayer(); + // have to be overlapping with the mushroom quite a bit + this->markForRemoval = true; + score += 1000; // todo: increase lives + } + } + break; + } + case Enemy_Flower: + case Enemy_Time: { + if (mushroom.risingTimer > 0.0f) { + if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) { + mushroom.risingTimer -= fElapsedTime; + posY -= fElapsedTime; + if (mushroom.risingTimer <= 0.0f) { + mushroom.risingTimer = 0.0f; + } + } + } else { + // gravity + velY += 20.0f * fElapsedTime; + isOnGround = false; + for (int i = 0; i < 5; i++) { + float newX = posX + fElapsedTime * velX * .2f; + float newY = posY + fElapsedTime * velY * .2f; + + if (velX < 0) { + if (IsSolid(GetTile(newX + 0.0f, posY + 0.0f), DIR_LEFT) || + IsSolid(GetTile(newX + 0.0f, posY + 0.9f), DIR_LEFT)) { + velX = -velX; + newX = (int)newX + 1; + } + } else if (velX > 0) { + if (IsSolid(GetTile(newX + 1.0f, posY + 0.0f), DIR_RIGHT) || + IsSolid(GetTile(newX + 1.0f, posY + 0.9f), DIR_RIGHT)) { + velX = -velX; + newX = (int)newX; + } + } + if (velY < 0) { + // no triggering blocks + if (IsSolid(GetTile(newX + 0.0f, newY), DIR_UP) || + IsSolid(GetTile(newX + 0.9f, newY), DIR_UP)) { + velY = 0; + newY = (int)newY + 1; + } + } + if (velY > 0) { + if (IsSolid(GetTile(newX + 0.0f, newY + 1.0f), DIR_DOWN) || + IsSolid(GetTile(newX + 0.9f, newY + 1.0f), DIR_DOWN)) { + velY = 0; + newY = (int)newY; + } + } + posX = newX; posY = newY; + } + Rectangle ri = { (int)(posX * 100), (int)(posY * 100), 100, 100}; + // offset the player rectangle a bit to avoid collecting while inside the box + Rectangle rp = { (int)(fPlayerPosX * 100 + 20), (int)(fPlayerPosY * 100), 100, 80 }; + if (RectangleIntersect(ri, rp)) { + // have to be overlapping with the mushroom quite a bit + this->markForRemoval = true; + score += 1000; + if (type == Enemy_Time) { + inGameTime += 10.f; + } else { + DamagePlayer(); + } + } + } + break; + } + } +} + +void Enemy::CommonDrawAtOffset(glImage* img, float pX, float pY, float oX, float oY, int flipMode) { + int sx = (posX - oX) * 16; + int sy = (posY - oY) * 16 + 1; + //glSprite(sx, sy, flipMode, img); + DrawImage(img, img->width, img->height, sx, sy); +} + +void Enemy::Draw (float fOffsetX, float fOffsetY) { + glImage* toDraw = nullptr; + int flipMode = 0; + switch (type) { + case Enemy_Mushroom: { + flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0; + // This should move the mushroom to behind the blocks during its rise anim + if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) { + CommonDrawAtOffset(&tilesImage[33], posX, posY, fOffsetX, fOffsetY, flipMode); + if (homeX != 0 || homeY != 0) { + int mx = (homeX - fOffsetX) * 16; + int my = (homeY - fOffsetY) * 16; + DrawTile('U',mx,my,'.'); + } + } + break; + } + case Enemy_Flower: { + flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0; + // This should move the mushroom to behind the blocks during its rise anim + if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) { + CommonDrawAtOffset(&tilesImage[36], posX, posY, fOffsetX, fOffsetY, flipMode); + if (homeX != 0 || homeY != 0) { + int mx = (homeX - fOffsetX) * 16; + int my = (homeY - fOffsetY) * 16; + DrawTile('U',mx,my,'.'); + } + } + break; + } + case Enemy_Time: { + flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0; + // This should move the mushroom to behind the blocks during its rise anim + if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) { + CommonDrawAtOffset(&tilesImage[37], posX, posY, fOffsetX, fOffsetY, flipMode); + if (homeX != 0 || homeY != 0) { + int mx = (homeX - fOffsetX) * 16; + int my = (homeY - fOffsetY) * 16; + DrawTile('U',mx,my,'.'); + } + } + break; + } + case Enemy_LifeUp: { + flipMode = this->mushroom.movingLeft ? GL_FLIP_H : 0; + // This should move the mushroom to behind the blocks during its rise anim + if ((BlockBumpedX != (int)homeX || BlockBumpedY != (int)homeY)) { + CommonDrawAtOffset(&tilesImage[38], posX, posY, fOffsetX, fOffsetY, flipMode); + if (homeX != 0 || homeY != 0) { + int mx = (homeX - fOffsetX) * 16; + int my = (homeY - fOffsetY) * 16; + DrawTile('U',mx,my,'.'); + } + } + break; + } + case Enemy_Zombie: + flipMode = this->zombie.movingLeft ? GL_FLIP_H : 0; + toDraw = &zombieImage[1]; + CommonDrawAtOffset(toDraw, posX, posY, fOffsetX, fOffsetY, flipMode); + break; + } +} + +void Enemy::CommonLoad() { + mushroomImage = &tilesImage[33]; + decompress(zombieBitmap, zombieBmp, LZ77); + zombSpriteID = glLoadTileSet(zombieImage,16,16,128,16, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_16, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)zombieBmp); +} \ No newline at end of file diff --git a/source/Enemy.hpp b/source/Enemy.hpp new file mode 100644 index 0000000..29a84fa --- /dev/null +++ b/source/Enemy.hpp @@ -0,0 +1,31 @@ +#include "TestGame.hpp" + +#define Enemy_Mushroom 1 +#define Enemy_Zombie 2 +#define Enemy_Flower 3 +#define Enemy_Time 4 +#define Enemy_LifeUp 5 + +class Enemy { +public: + int type; + float posX = 0, posY = 0; + float homeX = 0, homeY = 0; + float velX = 0, velY = 0; + bool isOnGround = false; + bool markForRemoval = false; + union { + struct { + bool movingLeft = false; + float risingTimer = 0.0f; + } mushroom; + struct { + bool movingLeft = false; + } zombie; + }; + Enemy(); ~Enemy(); + void CommonDrawAtOffset(glImage* img, float pX, float pY, float oX, float oY, int flipMode); + void Update(float deltaTime); + void Draw(float fOffsetX, float fOffsetY); + static void CommonLoad(); +}; \ No newline at end of file diff --git a/source/Engine.h b/source/Engine.h new file mode 100644 index 0000000..ac55737 --- /dev/null +++ b/source/Engine.h @@ -0,0 +1,674 @@ +#ifndef DS_GAME_ENGINE_INCL +#define DS_GAME_ENGINE_INCL + +#include "EngineDec.h" +#include "Map.h" +#include + +/* +int round(float f){ + float decpt = f - (int)f; + if(decpt < 0.5f){ + return (int)f; + }else{ + return (int)f+1; + } +}*/ + +short screenbuffer_maindisplay[49152]; +short screen_width = 256; +short screen_height = 192; + +uint32_t input_keys = 0; +uint32_t input_keysUp = 0; +uint32_t input_keysDown = 0; +uint32_t input_keysHeld = 0; + +uint8_t GraphScreen; + +touchPosition touch; +touchPosition prevTouch; +PrintConsole bottomScreen; + +#define PlotPixel2(x,y,c) screenbuffer_maindisplay[(y)*256+(x)]=c + +bool GetKeyState(uint32_t button){ + uint32_t s = input_keys & button; + return s; +} +bool GetKeyDownState(uint32_t button){ + uint32_t s = input_keysDown & button; + return s; +} +bool GetKeyUpState(uint32_t button){ + uint32_t s = input_keysUp & button; + return s; +} +bool GetKeyHeldState(uint32_t button){ + uint32_t s = input_keysHeld & button; + return s; +} +/* +void PushFrame(){ + if(GraphScreen == SCREEN_BOTTOM) + { + dmaCopy(&screenbuffer_maindisplay, BG_GFX_SUB, 49152*2); + } + else + { + dmaCopy(&screenbuffer_maindisplay, BG_GFX, 49152*2); + } +} + +void SwitchScreenBottom() +{ + GraphScreen = SCREEN_TOP; + // Console is on bottom screen + videoSetMode(MODE_5_2D); + //videoSetModeSub(MODE_0_2D); + + vramSetBankA(VRAM_A_MAIN_BG); + //vramSetBankC(VRAM_C_SUB_BG); + + bgInit(2, BgType_Bmp16, BgSize_B16_256x256, 0,0); + + //consoleInit(&topScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true); + consoleInit(&bottomScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true); + ClearScreen(0x0000); + PushFrame(); +} +void SwitchScreenTop() +{ + GraphScreen = SCREEN_BOTTOM; + // Console is on top screen + //videoSetModeSub(MODE_5_2D); + videoSetMode(MODE_0_2D); + + vramSetBankA(VRAM_A_MAIN_BG); + //vramSetBankC(VRAM_C_SUB_BG); + + //bgInitSub(2, BgType_Bmp16, BgSize_B16_256x256, 0,0); + + //consoleInit(&topScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true); + consoleInit(&bottomScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, true, true); + ClearScreen(0x0000); + PushFrame(); +} + +void PlotPixel (int x, int y, short colour) +{ + if((x) >= 0 && (x) < 256 && (y) >= 0 && (y) < 192){ + screenbuffer_maindisplay[y*screen_width+x] = colour; + } +} + +void ClearScreen(short colour){ + for(int x = 0; x < 49152; x+=1){ + //PlotPixel(x % 256, x / 256, colour); + screenbuffer_maindisplay[x]=colour; + } +} + +void FillRectangle(short colour, int dx, int dy, int w, int h){ + for(int y = 0; y < h; y++){ + for(int x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + PlotPixel2(x+dx, dy+y, colour); + } + } + } +} +void FillRectangleLerp(short colour1, short colour2, int dx, int dy, int w, int h){ + for(int y = 0; y < h; y++){ + for(int x = 0; x < w; x++){ + short colour = color_lerp(colour1, colour2, x * 255 / w); + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + PlotPixel2(x+dx, dy+y, colour); + } + } + } +} +void DrawRectangle(short colour, int dx, int dy, int w, int h){ + int x = 0; + for(x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256){ + PlotPixel2((x + dx), dy, colour); + } + } + for(x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256){ + PlotPixel2((x + dx), (dy - 1 + h), colour); + } + } + for(x = 0; x < h; x++){ + if((x+dx) >= 0 && (x+dx) < 256){ + PlotPixel2((dx), (x + dy), colour); + } + } + for(x = 0; x < h; x++){ + if((x+dx) >= 0 && (x+dx) < 256){ + PlotPixel2((w + dx - 1), (x + dy), colour); + } + } +} + +void DrawLine (int x1, int y1, int x2, int y2, short col){ + int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i; + dx = x2 - x1; dy = y2 - y1; + dx1 = abs(dx); dy1 = abs(dy); + px = 2 * dy1 - dx1; py = 2 * dx1 - dy1; + if (dy1 <= dx1) + { + if (dx >= 0) + { x = x1; y = y1; xe = x2; } + else + { x = x2; y = y2; xe = x1;} + + PlotPixel2(x, y, col); + + for (i = 0; x0 && dy>0)) y = y + 1; else y = y - 1; + px = px + 2 * (dy1 - dx1); + } + PlotPixel2(x, y, col); + } + } + else + { + if (dy >= 0) + { x = x1; y = y1; ye = y2; } + else + { x = x2; y = y2; ye = y1; } + + PlotPixel2(x, y, col); + + for (i = 0; y0 && dy>0)) x = x + 1; else x = x - 1; + py = py + 2 * (dx1 - dy1); + } + PlotPixel2(x, y, col); + } + } +} + +void DrawTriangle (int x1, int y1, int x2, int y2, int x3, int y3, short colour){ + DrawLine (x1, y1, x2, y2, colour); + DrawLine (x1, y1, x3, y3, colour); + DrawLine (x3, y3, x2, y2, colour); +} + +void FillTriangle (int x1, int y1, int x2, int y2, int x3, int y3, short col){ + / * Ripped from OneLoneCoder/ConsoleGameEngine * / + int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i; + dx = x2 - x1; dy = y2 - y1; + dx1 = abs(dx); dy1 = abs(dy); + px = 2 * dy1 - dx1; py = 2 * dx1 - dy1; + if (dy1 <= dx1) + { + if (dx >= 0) + { x = x1; y = y1; xe = x2; } + else + { x = x2; y = y2; xe = x1;} + + PlotPixel2(x, y, col); + DrawLine(x, y, x3, y3, col); + + for (i = 0; x0 && dy>0)) y = y + 1; else y = y - 1; + px = px + 2 * (dy1 - dx1); + } + PlotPixel2(x, y, col); + DrawLine(x, y, x3, y3, col); + } + } + else + { + if (dy >= 0) + { x = x1; y = y1; ye = y2; } + else + { x = x2; y = y2; ye = y1; } + + PlotPixel2(x, y, col); + DrawLine(x, y, x3, y3, col); + + for (i = 0; y0 && dy>0)) x = x + 1; else x = x - 1; + py = py + 2 * (dx1 - dy1); + } + PlotPixel2(x, y, col); + DrawLine(x, y, x3, y3, col); + } + } +} + +void DrawImageSizable(short* image, int w, int h, int dx, int dy, int dw, int dh){ + / *float pixel_width = dw / w; + float pixel_height= dh / h; + + for(int y = 0; y < dh; y++){ + for(int x = 0; x < dw; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + int src_y = round(y * pixel_height); + int src_x = round(x * pixel_width); + screenbuffer_maindisplay[(dy+y)*screen_width+(x+dx)] = image[(src_y*w+src_x)]; + } + } + }* / + + int w2 = dw, w1 = w, h2 = dh, h1 = h; + + // EDIT: added +1 to account for an early rounding problem + int x_ratio = (int)((w1<<16)/w2) +1; + int y_ratio = (int)((h1<<16)/h2) +1; + + int x2, y2 ; + for (int i=0;i>16) ; + y2 = ((i*y_ratio)>>16) ; + if((j+dx) >= 0 && (j+dx) < 256 && (i+dy) >= 0 && (i+dy) < 192){ + PlotPixel2(j+dx,i+dy,image[(y2*w1)+x2]); + } + } + } +} + +void DrawImage(short* image, int w, int h, int dx, int dy){ + for(int y = 0; y < h; y++){ + for(int x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + if(image[y*w+x] == -993){}else{ + PlotPixel2(x+dx,y+dy,image[y*w+x]); + } + } + } + } +} + +void DrawImageCrop(short* image, int w, int h, int dx, int dy, int sx, int sy, int dw, int dh){ + for(int y = 0; y < dh; y++){ + for(int x = 0; x < dw; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + if(image[(sy+y)*w+(sx+x)] == -993){}else{ + PlotPixel2(x+dx,y+dy,image[(sy+y)*w+(sx+x)]); + } + } + } + } +} + +void DrawImageCropFlipH(short* image, int w, int h, int dx, int dy, int sx, int sy, int dw, int dh){ + for(int y = 0; y < dh; y++){ + for(int x = 0; x < dw; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + if(image[(sy+y)*w+(sx+dw-1-x)] == -993){}else{ + PlotPixel2(x+dx,y+dy,image[(sy+y)*w+(sx+dw-1-x)]); + } + } + } + } +} + +void DrawImageFlippedV(short* image, int w, int h, int dx, int dy){ + for(int y = 0; y < h; y++){ + for(int x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + if(image[(h-y-1)*w+x] == -993){}else{ + PlotPixel2(x+dx,y+dy,image[(h-y-1)*w+x]); + } + } + } + } +} +void DrawImageFlippedHV(short* image, int w, int h, int dx, int dy){ + for(int y = 0; y < h; y++){ + for(int x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + if(image[(h-y)*w+(w-x-1)] == -993){}else{ + PlotPixel2(x+dx,y+dy,image[(h-y)*w+(w-x-1)]); + } + } + } + } +} +void DrawImageFlippedH(short* image, int w, int h, int dx, int dy){ + for(int y = 0; y < h; y++){ + for(int x = 0; x < w; x++){ + if((x+dx) >= 0 && (x+dx) < 256 && (y+dy) >= 0 && (y+dy) < 192){ + if(image[y*w+(w-x-1)] == -993){}else{ + PlotPixel2(x+dx,y+dy,image[y*w+(w-x-1)]); + } + } + } + } +}*/ + +void PushFrame() { + glFlush(0); +} + +void PlotPixel(int x, int y, short color) { + // todo + glPutPixel(x, y, 0xffff); +} + +typedef struct { + union { + struct { + u8 r,g,b,a; + }; + u32 c; + }; +} color_t; + +inline float MapX(int x) { + double f = (double)x / 128.0 * .935; + f -= .935; + return (float)f; +} +inline float MapY(int y) { + double f = (191 - y) / 96.0 * .7; + f -= .7; + return (float)f; +} +color_t MakeColort(short color) { + color_t c; + c.r = (color & 0x1f) * 8; + c.g = ((color >> 5) & 0x3f) >> 2; + c.b = ((color >> 11) & 0x1f); + c.a = ((color & 0x8000) ? 31 : 0) << 3; + return c; +} + +void ClearScreen(short color) { + color_t c = MakeColort(color); + glClearColor(c.r, c.g, c.b, c.a); +} +#define fv floattov16 +void FillRectangle(short color, int dx, int dy, int w, int h) { + glBoxFilled(dx,dy,dx+w,dy+h,color); +} +void FillRectangleLerp(short co1, short co2, int dx, int dy, int w, int h) +{ + glBoxFilledGradient(dx,dy,dx+w,dy+h,co1,co1,co2,co2); +} +void DrawRectangle(short color, int dx, int dy, int w, int h) { + glBox(dx,dy,dx+w,dy+h,color); +} +void DrawLine(int x1, int y1, int x2, int y2, short col) { + glLine(x1,y1,x2,y2,MakeColort(col).c); +} +int GetGLTexSizeEnum(int w) { + /**/ if (w <= 8) return TEXTURE_SIZE_8; + else if (w <= 16) return TEXTURE_SIZE_16; + else if (w <= 32) return TEXTURE_SIZE_32; + else if (w <= 64) return TEXTURE_SIZE_64; + else if (w <= 128) return TEXTURE_SIZE_128; + else if (w <= 256) return TEXTURE_SIZE_256; + else if (w <= 512) return TEXTURE_SIZE_512; + else if (w <= 1024) return TEXTURE_SIZE_1024; + return TEXTURE_SIZE_1024; +} +int imageIDsReserved[TEXTURE_COUNT]; +int nextImageIdx; +int LoadImageVRAM(short* image, int w, int h) { + bool b = glTexImage2D(imageIDsReserved[nextImageIdx], 0, GL_RGBA, GetGLTexSizeEnum(w),GetGLTexSizeEnum(h), 0, 0, image); + LogMsg("Loading image with size %dx%d (it got id %d) was %s", w, h,imageIDsReserved[nextImageIdx], b ? "successful":"unsuccessful"); + return imageIDsReserved[nextImageIdx++]; +} +void FillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short colour) { + glTriangleFilled(x1,y1,x2,y2,x3,y3,colour); +} +void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short colour) { + glTriangle(x1,y1,x2,y2,x3,y3,colour); +} +void DrawImageSizable(glImage* image, int w, int h, int dx, int dy, int dw, int dh){} +void SwitchScreenTop(){} +void SwitchScreenBottom(){} + +static v16 g_depth; +static inline void gxVertex3i_re(v16 x, v16 y, v16 z) +{ + GFX_VERTEX16 = (y << 16) | (x & 0xFFFF); + GFX_VERTEX16 = ((uint32)(uint16)z); +} +static inline void gxTexcoord2i_re(t16 u, t16 v) +{ + GFX_TEX_COORD = (v << 20) | ( (u << 4) & 0xFFFF ); +} +static inline void gxVertex2i_re(v16 x, v16 y) +{ + GFX_VERTEX_XY = (y << 16) | (x & 0xFFFF); +} +void DrawImageColored(glImage* spr, int w, int h, int dx, int dy, int flipmode, u16 color) { + // Cannot use glSprite, gotta recreate it + /* + int x1 = dx; + int y1 = dy; + int x2 = dx + spr->width; + int y2 = dy + spr->height; + + int u1 = spr->u_off + (( flipmode & GL_FLIP_H ) ? spr->width-1 : 0); + int u2 = spr->u_off + (( flipmode & GL_FLIP_H ) ? 0 : spr->width); + int v1 = spr->v_off + (( flipmode & GL_FLIP_V ) ? spr->height-1 : 0); + int v2 = spr->v_off + (( flipmode & GL_FLIP_V ) ? 0 : spr->height); + + + + if ( spr->textureID != gCurrentTexture ) + { + glBindTexture( GL_TEXTURE_2D, spr->textureID ); + gCurrentTexture = spr->textureID; + } + + glBegin( GL_QUADS ); + glColor(color);gxTexcoord2i_re( u1, v1 ); gxVertex3i_re( x1, y1, g_depth ); + glColor(color);gxTexcoord2i_re( u1, v2 ); gxVertex2i_re( x1, y2 ); + glColor(color);gxTexcoord2i_re( u2, v2 ); gxVertex2i_re( x2, y2 ); + glColor(color);gxTexcoord2i_re( u2, v1 ); gxVertex2i_re( x2, y1 ); + glEnd(); + g_depth++; + glColor(0x7FFF);*/ + glColor(color); + glSprite(dx, dy, flipmode, spr); + glColor(0x7FFF); +} +void DrawImageINT(glImage* image, int w, int h, int dx, int dy, int fm) { + glSprite(dx, dy, fm, image); +} +void DrawImageFlippedH (glImage* image, int w, int h, int dx, int dy) { + DrawImageINT(image, w, h, dx, dy, GL_FLIP_H); +} +void DrawImageFlippedHV(glImage* image, int w, int h, int dx, int dy) { + DrawImageINT(image, w, h, dx, dy, GL_FLIP_H|GL_FLIP_V); +} +void DrawImageFlippedV (glImage* image, int w, int h, int dx, int dy) { + DrawImageINT(image, w, h, dx, dy,GL_FLIP_V); +} +void DrawImage(glImage* image, int w, int h, int dx, int dy) { + DrawImageINT(image,w,h,dx,dy,0); +} +void DrawImageCrop(glImage* image, int w, int h, int dx, int dy, int sx, int sy, int dw, int dh) { + DrawImage(image, w, h, dx, dy); + //DrawRectangle(RED, dx, dy, dw, dh); +} +void DrawImageCropFlipH(glImage* image, int w, int h, int dx, int dy, int sx, int sy, int dw, int dh) { + DrawImageFlippedH(image, w, h, dx, dy); + //DrawRectangle(RED, dx, dy, dw, dh); +} +#undef fv +uint16_t GlobalTimer = 0; + +void OnUserCreate(); +void OnUserUpdate(); + +void InitConsoleScreen() {consoleSelect(&bottomScreen);} +void PrintChar(char x, char y, char c) { printf("\x1b[%d;%dH%c", y, x, c); } + +void DoEverySecond() { + LogMsg("test"); +} +int game_ticks = 0; +int millisSinceRun = 0; + +int fpsCounting, fps, prevS; + +#include "bmpfont.h" +short font_bmp[1024*8]; +int fontSpriteID; +glImage fontImage[128]; + +int main(void) { + //videoSetModeSub(MODE_5_2D); + lcdMainOnBottom(); + videoSetMode(MODE_5_3D); + videoSetModeSub(MODE_0_2D); + + // init gl2d + glScreen2D(); + glEnable(GL_ANTIALIAS); + vramSetBankA( VRAM_A_TEXTURE ); + vramSetBankB( VRAM_B_TEXTURE ); + + soundEnable(); + + bgInitSub(2, BgType_Bmp16, BgSize_B16_256x256, 0,0); + + consoleInit(&bottomScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true); + + InitConsoleScreen(); + + timerStart(0, ClockDivider_1024, 0, NULL); + + glGenTextures(TEXTURE_COUNT, imageIDsReserved); + // load font shit + decompress(bmpfontBitmap,font_bmp,LZ77); + fontSpriteID = glLoadTileSet(fontImage, 6,8,1024,8, GL_RGBA, TEXTURE_SIZE_1024, TEXTURE_SIZE_8, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)font_bmp); + + OnUserCreate(); + while(1) { + glBegin2D(); + fpsCounting++; + game_ticks += timerElapsed(0); + uint64_t r = game_ticks * 1000llu; + r /= TIMER_SPEED; + millisSinceRun = r; + + int s = millisSinceRun / 1000; + if (prevS != s) { + fps = fpsCounting; + fpsCounting = 0; + } + prevS = s; + + prevTouch = touch; + touchRead(&touch); + scanKeys(); + + input_keys = keysCurrent(); + input_keysUp = keysUp(); + input_keysDown = keysDown(); + input_keysHeld = keysHeld(); + + OnUserUpdate(); + char str[100]; + memset(str,0,100); + sprintf(str, "fps: %d", fps); + DrawString(2, 184, BLACK, str, 0); + DrawString(1, 183, WHITE, str, 0); + + GlobalTimer++; + glEnd2D(); + PushFrame(); + g_depth = 4000; + swiWaitForVBlank(); + } + + return 0; +} + +bool RectangleContains(Rectangle r, Point p) { + return (r.x <= p.x && r.y <= p.y && r.x + r.width > p.x && r.y + r.height > p.y); +} + +bool RectangleIntersect(Rectangle r1, Rectangle r2) { + int playerX1 = r1.x, playerX2 = r1.x + r1.width, playerY1 = r1.y, playerY2 = r1.y + r1.height; + int tileRectX1 = r2.x, tileRectX2 = r2.x + r2.width, tileRectY1 = r2.y, tileRectY2 = r2.y + r2.height; + bool noOverlap = tileRectX1 > playerX2 || + playerX1 > tileRectX2 || + tileRectY1 > playerY2 || + playerY1 > tileRectY2; + return !noOverlap; +} + +/*int dx = x2 - x1; + int dy = y2 - y1; + + if (dx >= dy){ + float y = 0.0f; + if(x1 < x2){ + for (int x = x1; x <= x2; x++) { + y = y1 + dy * (x - x1) / dx; + PlotPixel(x, y, colour); + } + }else{ + for (int x = x2; x <= x1; x++) { + y = y1 + dy * (x - x1) / dx; + PlotPixel(x, y, colour); + } + } + }else{ + float x = 0.0f; + if(dx == 0){ + if(y1 < y2){ + for (int y = y1; y <= y2; y++) { + PlotPixel(x1, y, colour); + } + }else{ + for (int y = y2; y <= y1; y++) { + PlotPixel(x2, y, colour); + } + } + }else{ + if(y1 < y2){ + for (int y = y1; y <= y2; y++) { + x = x1 + dx * (y - y1) / dy; + PlotPixel(x, y, colour); + } + }else{ + for (int y = y2; y <= y1; y++) { + x = x1 + dx * (y - y1) / dy; + PlotPixel(x, y, colour); + } + } + } + }*/ + +#include "Features/RNG.h" +#include "Font.h" + +#endif diff --git a/source/EngineDec.h b/source/EngineDec.h new file mode 100644 index 0000000..0fe36e7 --- /dev/null +++ b/source/EngineDec.h @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + Programmed by iProgramInCpp + + EngineDec module +---------------------------------------------------------------------------------*/ +#ifndef ENGINEDEC_H +#define ENGINEDEC_H + +#include "Utils.hpp" +#include + +#define TIMER_SPEED (BUS_CLOCK/1024) + +// 16 bit color is structured in 1555 format +// EBGR +// E - enable bit / alpha +// RGBA16 + +#define WHITE 0xFFFF +#define BLACK 0x0000 +#define SKY 0xEEEF +#define BLUE 0xFC00 +#define MAGENTA 0xFC1F +#define CYAN 0xFFE0 +#define RED 0x801F +#define YELLOW 0x83FF + +//#define RGBA16(r,g,b,a) ((r << 11) | (g << 6) | (b << 1) | a) +#define RGBA16(r,g,b,a) ((a << 15) | (b << 10) | (g << 5) | r) +#define MakeColor5B(r,g,b) RGBA16(r,g,b,1) +#define MakeColor(r,g,b) RGBA16(r/8,g/8,b/8,1) + +#include +#include + +#define SCREEN_BOTTOM 1 +#define SCREEN_TOP 2 + +#define STYLE_BOLD 0x80 +#define STYLE_ITALIC 0x40 +#define STYLE_UNDERLINE 0x20 + +#define LAYER_FORE 0 +#define LAYER_BACK 1 + +#define TEXTURE_COUNT 16 +extern int imageIDsReserved[TEXTURE_COUNT]; + +bool GetKeyState(uint32_t button); +bool GetKeyDownState(uint32_t button); +bool GetKeyUpState(uint32_t button); +bool GetKeyHeldState(uint32_t button); +void PushFrame(); +void PlotPixel(int x, int y, short color); +void ClearScreen(short color); +void FillRectangle(short color, int dx, int dy, int w, int h); +void FillRectangleLerp(short c1, short c2, int dx, int dy, int w, int h); +void DrawRectangle(short color, int dx, int dy, int w, int h); +void DrawLine(int x1, int y1, int x2, int y2, short col); +void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short colour); +void FillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short colour); +void DrawImageSizable(glImage* image, int w, int h, int dx, int dy, int dw, int dh); +void SwitchScreenTop(); +void SwitchScreenBottom(); +void DrawImageFlippedH (glImage* image, int w, int h, int dx, int dy); +void DrawImageFlippedHV(glImage* image, int w, int h, int dx, int dy); +void DrawImageFlippedV (glImage* image, int w, int h, int dx, int dy); +void PrintChar(char x, char y, char c); +void InitConsoleScreen(); +uint16_t map(uint16_t min, uint16_t max, uint8_t h); +uint16_t color_lerp(uint16_t min, uint16_t max, uint16_t i); +void DrawChar(uint16_t x, uint16_t y, char ch, uint16_t color, uint8_t styling); +void DrawString(uint8_t x, uint8_t y, uint16_t color, const char* str, uint8_t styling); +void DrawImage(glImage* image, int w, int h, int dx, int dy); +void DrawImageCrop(glImage* image, int w, int h, int dx, int dy, int sx, int sy, int dw, int dh); +void DrawImageCropFlipH(glImage* image, int w, int h, int dx, int dy, int sx, int sy, int dw, int dh); +void DrawImageColored(glImage* spr, int w, int h, int dx, int dy, int flipmode, u16 color); + +#define GetBlueComponent(i) (i & 0x7c00) >> 10 +#define GetGreenComponent(i) (i & 0x03e0) >> 5 +#define GetRedComponent(i) (i & 0x001f) + +#define Unite(r, g, b) 0x8000 | (b << 10) | (g << 5) | r + +extern touchPosition touch, prevTouch; +extern int fps; +extern uint16_t GlobalTimer; + +struct Rectangle { + int x, y, width, height; +}; +struct Point { + int x, y; +}; +typedef Point Point2d; +struct Point3d { + int x, y, z; +}; +struct Vec3f { + float x, y, z; +}; +struct Vec2f { + float x, y; +}; +bool RectangleContains(Rectangle r, Point p); +bool RectangleIntersect(Rectangle r1, Rectangle r2); + +#endif//ENDINEDEC_H \ No newline at end of file diff --git a/source/Features/RNG.h b/source/Features/RNG.h new file mode 100644 index 0000000..da56356 --- /dev/null +++ b/source/Features/RNG.h @@ -0,0 +1,22 @@ +unsigned short rng; + +short sky_colour = 0xEEEF; + +unsigned short rng_function(unsigned short input){ + if(input == 0x560A) input=0; + unsigned short S0 = (unsigned char)input<<8; + S0 = S0 ^ input; + input = ((S0 & 0xFF) << 8) | ((S0 & 0xFF00) >> 8); + S0 = ((unsigned char)S0 << 1) ^ input; + short S1 = (S0 >> 1) ^ 0xFF80; + if((S0 & 1) == 0){ + if(S1 == 0xAA55){input = 0;}else{input=S1 ^ 0x1FF4;} + }else{ + input = S1 ^ 0x1FF4; + } + return (unsigned short)input; +} + +void rng_update() { + rng = rng_function(GlobalTimer); +} diff --git a/source/Font.h b/source/Font.h new file mode 100644 index 0000000..df68e92 --- /dev/null +++ b/source/Font.h @@ -0,0 +1,77 @@ +#include "Typeface.h" +void DrawCharOld(uint16_t x, uint16_t y, char ch, uint16_t color, uint8_t styling) +{ + uint16_t address = ch * 5; + uint8_t n = 0; + uint16_t new_x = x + n; + uint16_t new_y; + uint8_t a; + uint16_t m = 4; + if((styling & STYLE_ITALIC) == 0) + { + m = 0; + } + for (n = 0; n < 5; n++) + { + new_x = x + n; + a = MainFont[address + n]; + if((styling & STYLE_ITALIC) != 0) + { + m = 4; + } + for(new_y = 0; new_y < 8; new_y++) + { + if(a & (0x01 << new_y)) + { + if((styling & STYLE_BOLD) != 0) + { + PlotPixel(new_x + m + 1, new_y + y, color); + } + PlotPixel(new_x + m, y + new_y, color); + } + if((styling & STYLE_ITALIC) != 0 && new_y % 3 == 0) { m--; } + } + if((styling & STYLE_UNDERLINE) != 0) + { + PlotPixel(new_x - 1, y + 7, color); + PlotPixel(new_x, y + 7, color); + PlotPixel(new_x + 1, y + 7, color); + } + } +} + +void DrawChar(uint16_t x, uint16_t y, char ch, uint16_t color, uint8_t styling) { + // italic and uline ignored for now, might add it later + if (ch >= 128) ch = 127; + DrawImageColored(&fontImage[(int)ch], 6, 8, x, y, 0, color); + if (styling & STYLE_BOLD) { + DrawImageColored(&fontImage[(int)ch], 6, 8, x+1, y, 0, color); + } +} +void DrawString(uint8_t x, uint8_t y, uint16_t color, const char* str, uint8_t styling) +{ + const char* m = str; + uint8_t ny = y; + uint8_t nx = x; + while(*m != 0) + { + if(*m == '\n') + { + nx = x; + ny += 8; + } + else + { + DrawChar(nx, ny, *m, color, styling); + if((styling & STYLE_BOLD) != 0) + { + nx += 7; + } + else + { + nx += 6; + } + } + m++; + } +} \ No newline at end of file diff --git a/source/Levels.inc.h b/source/Levels.inc.h new file mode 100644 index 0000000..134a53b --- /dev/null +++ b/source/Levels.inc.h @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + ProDrammed by iProDramInCpp + + Level include file +---------------------------------------------------------------------------------*/ +char level_1[] = + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "................................................................................................................................................................................................................................................................" + "..{S............................................................................................................................................................................................................................................................" + "GGGGGG.........................................................................................................................................................................................................................................................." + "GGGGGG.........................................................................................................................................................................................................................................................."; +char level_1_old[] = + "...................................................................................................................................................................................................oo............oo.........oo.................................." + ".......................................................................................oooooooooooo............................................................................................===================================.............................." + "............................?.................................................................................==?==..................................................................=========.........................................1!..................^...." + "....................................................................................BBBBBBBBBBBBBBBBBB.................................................................................................................................~`......................." + ".............................................................................................................................................................................=====....................................................=~`......................." + ".......................................................................................................................................................................................................................................~`......................." + "...^QAL..................BB?^?BB......................1!.......1!.............................................==^==......BB?BBBBBBB?BBBBBB?BB.......1!..............=====...............#.........................................??...~`....1!..........?.?.?.." + "...............................................1!.....~`.......~`................BBB........BBBBB...................................................~`..................................#.............................................=~`....~`......8.........." + "........................................1!.....~`.....~`.......~`...................................................................................~`......1!..........................#..............................................~`....~`................." + "..{S.(......&&...).......&......(...&...~`....)~`.....~`...(...~`............)..........(...&&........)...&.....&...(....&.....&....)......&.&.....(~`).....~`....)....&&.........(.....#...........................................(..~`....~`...&.&.&......).." + "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG.....GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG.........................................GGGGGGGGGGGGGGGGGGGGGGGGGGGG.." + "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.....DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.........................................DDDDDDDDDDDDDDDDDDDDDDDDDDDD.."; +int level_1_width = 256, level_1_height = 12; \ No newline at end of file diff --git a/source/Main.cpp b/source/Main.cpp new file mode 100644 index 0000000..f6d885c --- /dev/null +++ b/source/Main.cpp @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + Programmed by iProgramInCpp + + Main module +---------------------------------------------------------------------------------*/ +#include +#include +#include + +#include "Engine.h" +#include "Utils.hpp" +#include "TestGame.hpp" +/* + DS Game Engine Function Definitions + -- to keep in mind + + bool GetKeyState(uint32_t) + bool GetKeyDownState(uint32_t) + bool GetKeyUpState(uint32_t) + bool GetKeyHeldState(uint32_t) + void PushFrame(); + void PlotPixel(int x, int y, short color) + void ClearScreen(short color) + void FillRectangle(short color, int dx, int dy, int w, int h) + void FillRectangleLerp(short c1, short c2, int dx, int dy, int w, int h) + void DrawRectangle(short color, int dx, int dy, int w, int h) + void DrawLine(int x1, int y1, int x2, int y2, short col) + void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short colour) + void FillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, short colour) + void DrawImageSizable(short* image, int w, int h, int dx, int dy, int dw, int dh) + void SwitchScreenTop() + void SwitchScreenBottom() + void DrawImageFlippedH(short* image, int w, int h, int dx, int dy) + void DrawImageFlippedHV(short* image, int w, int h, int dx, int dy) + void DrawImageFlippedV(short* image, int w, int h, int dx, int dy) + void PrintChar(char x, char y, char c); + void InitConsoleScreen(); +*/ +bool isFileSystemEnabled = false; +void OnUserCreate() +{ + /*isFileSystemEnabled = fatInitDefault(); + FILE* f = fopen("/test.txt", "r"); + char s [15]; + memset(s,0,15); + if (!f) { + LogMsg("Unable to open file"); + } else { + fread(s, 1, 14, f); + fclose(f); + LogMsg("Got string: %s", s); + }*/ + //SwitchScreenBottom(); + //SwitchScreenTop(); + //InitConsoleScreen(); + printf("\n\n\n\n\n\n\n\n"); + printf(" Growalone Maker V%.2f ", 0.10); // game version + printf(" For Nintendo DS / DSi "); + //printf(" This is intended for use with "); + //printf("the touch screen. Please look at"); + //printf(" the bottom screen now. "); + //printf(" There is NOTHING to see here..."); + printf("\n"); + printf("NOTE: You can't save. This is a "); + printf("prototype. Saving will be added "); + printf(" later.... "); + + Game::Init(); + Game::LoadContent(); +} + + +void OnUserUpdate() +{ + rng_update(); + //ClearScreen(RGBA16(0, 12, 31, 1)); + Game::Update(); +} diff --git a/source/Map.h b/source/Map.h new file mode 100644 index 0000000..9878940 --- /dev/null +++ b/source/Map.h @@ -0,0 +1,31 @@ + + +// returns an integer between min and max using range from 0-255 +uint16_t map(uint16_t min, uint16_t max, uint8_t h) +{ + uint16_t i = max - min; + if(h == 0x00) return min; + else if(h == 255) return max; + else + { + uint16_t m = min + (h * i / 256); + return m; + } +} + +uint16_t color_lerp(uint16_t min, uint16_t max, uint16_t i) +{ + uint8_t mred = GetRedComponent(min); + uint8_t mgreen = GetGreenComponent(min); + uint8_t mblue = GetBlueComponent(min); + + uint8_t m2red = GetRedComponent(max); + uint8_t m2green = GetGreenComponent(max); + uint8_t m2blue = GetBlueComponent(max); + + uint8_t rred = map(mred, m2red, i); + uint8_t rgreen = map(mgreen, m2green, i); + uint8_t rblue = map(mblue, m2blue, i); + + return Unite(rred, rgreen, rblue); +} \ No newline at end of file diff --git a/source/TestGame.cpp b/source/TestGame.cpp new file mode 100644 index 0000000..43df9b3 --- /dev/null +++ b/source/TestGame.cpp @@ -0,0 +1,1427 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + Programmed by iProgramInCpp + + TestGame module +---------------------------------------------------------------------------------*/ + +#include "TestGame.hpp" +#include +#include +#include +#include +#include "character.h" +#include "tiles.h" +#include "clapperboard.h" +#include "undo.h" +#include "reset.h" +#include "erase.h" +#include "itemsel.h" +#include "item.h" +#include "lr_arrows.h" +#include "erase_mode.h" +#include "copy_mode.h" +#include "dialog_bg.h" +#include "dialogbtn.h" +#include "logo.h" +#include "Enemy.hpp" + +// todo: add save +/* +short tiles[128*128]; +short character[128*16]; +short clapperboard[128*64]; +short undoBmp[32*32]; +short eraseBmp[32*32]; +short lrArrowsBmp[32*32]; +short resetBmp[32*32]; +short itemSelBmp[32*32]; +short itemBmp[32*32]; +short ermodBmp[64*16]; +*/ + +short textureCacheBmp[256*256]; +bool hasPressedLROrStart = false; + + +bool isInCopyMode = false; +bool isDraggingStuff = false; +float worldDragPosX, worldDragPosY; +float lastWorldTouchPosX, lastWorldTouchPosY; +int draggedRectX1 = -1, draggedRectY1; +int draggedRectX2 = -1, draggedRectY2; + +#include "Levels.inc.h" + +char* sLevel, *sLevelBeforePlay; +int nLevelWidth, nLevelHeight; + +bool bPlayerOnGround = false; + +int nDirModX = 0, nDirModY = 0; + +float fCameraPosX = 0.0f, fCameraPosY = 0.0f; +float fPlayerPosX = 0.0f, fPlayerPosY = 0.0f; +float fPlayerVelX = 0.0f, fPlayerVelY = 0.0f; + +glImage tilesImage[64]; +glImage playrImage[9]; +glImage cbordImage[2]; +glImage resetImage[1]; +glImage eraseImage[1]; +glImage itemSImage[1]; +glImage itemImage[1]; +glImage lrArrowImage[2]; +glImage undoImage[1]; +glImage ermodImage[1]; +glImage cpmodImage[1]; +glImage dlgBgImage[1]; +glImage dlgBtnImage[1]; +glImage logoImage[1]; +int tileSpriteID, plyrSpriteID, cbrdSpriteID; +int lrArSpriteID; +int resetSpriteID; +int eraseSpriteID; +int itemSelSpriteID; +int itemSpriteID; +int undoSpriteID; +int ermodSpriteID; +int cpmodSpriteID; +int dlgBgSpriteID; +int dlgBtnSpriteID; +int logoSpriteID; + +enum GameMode { + Mode_Game, + Mode_Title, + Mode_Maker +}; +int gameMode = Mode_Title; + +const char* dialogRow1, *dialogRow2, *dialogRow3, *dialogYesText, *dialogNoText; +DialogResultFunction *dialogResultFunc; +bool dialogShown; +int dialogPosition = 192; + +void ShowDialog(DialogResultFunction* f, const char* dialogYes, const char* dialogNo, const char* dlgRow1, const char* dlgRow2, const char* dlgRow3) { + dialogYesText = dialogYes; + dialogNoText = dialogNo; + dialogRow1 = dlgRow1; + dialogRow2 = dlgRow2; + dialogRow3 = dlgRow3; + dialogResultFunc = f; + dialogShown = true; + dialogPosition = 192; +} + +void ResetLevel(bool yes); + +bool dialogButtonsClicked[2]; + +void DrawDialog(bool processTouch = true) { + DrawImage(dlgBgImage, 256, 192, 0, dialogPosition); + Rectangle rBtn[2] = { + { 20, 136, 96, 32 }, + { 138, 136, 96, 32 } + }; + + // draw text + int m = dialogPosition; + m += 50; + DrawString((SCREEN_WIDTH - strlen(dialogRow1) * 6) / 2, m, BLACK, dialogRow1, 0); + m += 9; + DrawString((SCREEN_WIDTH - strlen(dialogRow2) * 6) / 2, m, BLACK, dialogRow2, 0); + m += 9; + DrawString((SCREEN_WIDTH - strlen(dialogRow3) * 6) / 2, m, BLACK, dialogRow3, 0); + + bool clicked[2] = { 0, 0 }; + Point pTouch = { touch.px, touch.py }; + for (int i = 0; i < 2; i++) { + uint16_t color = 0xFFFF; + rBtn[i].y += dialogPosition; + if (processTouch) { + if (RectangleContains(rBtn[i], pTouch)) { + color &= 0xbdef; + clicked[i] = true; + } + } + DrawImageColored(dlgBtnImage, 128, 32, rBtn[i].x, rBtn[i].y, 0, color); + } + DrawString((96 - strlen(dialogNoText) * 6) / 2 + rBtn[0].x, rBtn[0].y + 12, BLACK, dialogNoText, 0); + DrawString((96 - strlen(dialogYesText) * 6) / 2 + rBtn[1].x, rBtn[1].y + 12, BLACK, dialogYesText, 0); + if (processTouch) { + for (int i = 0; i < 2; i++) { + if (!clicked[i] && dialogButtonsClicked[i]) { + ResetLevel(i); + dialogShown = false; + } + } + memcpy(dialogButtonsClicked, clicked, sizeof(clicked)); + } +} + +char GetTile(int x, int y){ + int cy = y; + if (y < 0) y = 0; + if(x >= 0 && x < nLevelWidth && y >= 0 && y < nLevelHeight){ + if (cy < y && sLevel[y*nLevelWidth+x] == 'o') return '.'; + return sLevel[y*nLevelWidth+x]; + }else{ + return ' '; + } +} + +void SetTile(char c, int x, int y){ + if(x >= 0 && x < nLevelWidth && y >= 0 && y < nLevelHeight){ + sLevel[y*nLevelWidth+x] = c; + } +} + +int GetDirModX() { + return nDirModX; +} +const char* makeText = "Make", *playText = "Play"; +bool hasClickedPreviously[2]; + +// enemy list +std::vector> enemies; + +float maxTime = 500; +int gems = 0, score = 0; +float inGameTime = maxTime; +bool isOnOffSwitchOn = true; +bool CanBeBumped(char c) { + switch (c) { + case '?': + case '^': + case 'Q': + case 'A': + case 'L': + case 'B': + case 'E': + return true; + } + return false; +} +bool ending = false; +int endingStage = 0; +bool IsSolid(char c, int directions) { + switch (c) { + case 'o': + case '(': + case ')': + case '{': + case '}': + case '&': + case '.': + case ' ': + case 'S': + case '0': + case '8': + return false; + case '=': + if (directions & DIR_DOWN) return true; + return false; + case 'F': + return !isOnOffSwitchOn; + case 'H': + return isOnOffSwitchOn; + default: + return true; + } +} + +void SpawnEnemy(const Enemy enemy) { + if (enemies.size() >= 100) { + //LogMsg("Enemy limit reached"); + return; + } + auto u = std::make_unique(enemy); + enemies.push_back(std::move(u)); +} + +void SpawnMushTypeRise(float x, float y, int type) { + Enemy mush; + mush.type = type; + mush.posX = mush.homeX = floorf(x); mush.posY = mush.homeY = floorf(y); + mush.mushroom.risingTimer = 1.0f; + SpawnEnemy(mush); +} + +int hp = 1, maxHP = 1; +float lastHP = 0.0f; +void IncreaseMaxHP() { + maxHP++; + hp = maxHP; +} + +void AddToMaxHP(int i) { + while (i > 0) { + IncreaseMaxHP(); + i--; + } +} + +#define State_Idle 0 +#define State_Jump 1 +#define State_Walk 2 +#define State_Run 3 +#define State_Skid 4 +#define State_Dead 5 +#define State_Crouch 6 +int playerState = State_Idle; + +float gameTimer = 0; +float deathTimer = 0.0f; +bool canEditLevel = false; +int dieStage = 0; +bool doPlayerFallAfterDeath = false; + +void ResetEverything(); +void KillPlayer(bool doInstantly) { + // play jingle, then wait a few seconds + deathTimer = 0.0f; + playerState = State_Dead; + dieStage = 0; + doPlayerFallAfterDeath = !doInstantly; + fPlayerVelY = fPlayerVelX = 0; +} +void LoadLevelToMem(char* c, int w, int h); +void DoLevelInitStuff(); + +bool doSetToMakerMode = false; + +float stunTimer = 0.0f; + +void DamagePlayer() { + if (stunTimer > 0.0f) return; + hp--; + if (hp <= 0) { + hp = 0; + KillPlayer(false); + return; + } + stunTimer = 4.0f; +} +void HealPlayer() { + hp++; + while (hp > maxHP) { + maxHP++; + } +} + +float BlockBumpTimer = 0.0f; +int BlockBumpedX = -1, BlockBumpedY = -1; +float endingTimer = 0; +void ResetEverything() { + isOnOffSwitchOn = true; + memcpy(sLevel, sLevelBeforePlay, nLevelHeight * nLevelWidth); + enemies.clear(); + hp = 1; + maxHP = 1; + inGameTime = 500; + gems = 0; + score = 0; + stunTimer = 0; + lastHP = 1; + ending = false; + endingStage = 0; + endingTimer = 0; +} +void SetToMakerMode() { + doSetToMakerMode = true; + BlockBumpTimer = 0.0f; + BlockBumpedX = BlockBumpedY = -1; + ResetEverything(); +} + +void SpawnBump(int x, int y) { + if (!CanBeBumped(GetTile(x,y))) return; + BlockBumpTimer = 0.0f; + BlockBumpedX = x; + BlockBumpedY = y; +} +void ResetLevel(bool yes) { + if (!yes) return; + //gameMode = Mode_Maker; + SetToMakerMode(); + LoadLevelToMem(level_1, level_1_width, level_1_height); + canEditLevel = true; +} + +void Game::UpdateGameLogic(float fElapsedTime) { + gameTimer += fElapsedTime; + stunTimer -= fElapsedTime; + if (stunTimer < 0) stunTimer = 0; + if (inGameTime >= -1 && playerState != State_Dead && !ending) { + inGameTime -= fElapsedTime; + } + if (inGameTime < 0 && !ending) { + inGameTime = 0; + KillPlayer(false); + } + /* + if (GetKeyState(KEY_UP)) { + fPlayerVelY = -6.0f; + } + if (GetKeyState(KEY_DOWN)) { + fPlayerVelY = 6.0f; + }*/ + + BlockBumpTimer += fElapsedTime; + if (BlockBumpTimer > .25f) { + BlockBumpTimer = 0.0f; + BlockBumpedX = BlockBumpedY = -1; + } + + if (gameMode == Mode_Game) { + if (canEditLevel) { + if (GetKeyDownState(KEY_SELECT) || GetKeyDownState(KEY_START)) { + SetToMakerMode(); + } + } + } + + if (endingStage == 1) { + if (inGameTime >= 10) { + inGameTime -= 10; + score += 100; + } + if (inGameTime >= 1) { + inGameTime--; + score += 10; + } else { + endingStage++; + endingTimer = 3; + } + } + if (endingStage == 2) { + endingTimer -= fElapsedTime; + if (endingTimer <= 0.0f) { + if (canEditLevel) { + SetToMakerMode(); + } + ResetEverything(); + DoLevelInitStuff(); + } + } + + if (playerState == State_Dead) { + deathTimer += fElapsedTime; + if (deathTimer >= 1.0f && doPlayerFallAfterDeath) { + if (dieStage == 0) { + dieStage++; + fPlayerVelY = -12.0f; + } else { + fPlayerVelY += 20.0f * fElapsedTime; + } + } + fPlayerPosX += fPlayerVelX * fElapsedTime; + fPlayerPosY += fPlayerVelY * fElapsedTime; // no collision + if (deathTimer >= 5.0f) { + if (canEditLevel) { + SetToMakerMode(); + } + ResetEverything(); + DoLevelInitStuff(); + } + } else { + if (fPlayerPosY > nLevelHeight + 3.0f) { + KillPlayer(true); + } + float addSpeed = 6.0f; + bool holdingRun = false; + if(GetKeyState(KEY_Y) || GetKeyState(KEY_X)){ + addSpeed += 8.0f; + holdingRun = true; + } + + float groundFriction = 6.0f; + bool hitDirKey = false; + if (!ending) { + if (playerState == State_Crouch) playerState = State_Idle; + if(GetKeyState(KEY_DOWN)){ + playerState = State_Crouch; + } + if(GetKeyState(KEY_LEFT) && playerState != State_Crouch){ + hitDirKey = true; + bool isSkidding = false; + if (playerState == State_Idle || playerState == State_Walk || playerState == State_Run || playerState == State_Skid) { + if (fPlayerVelX > 0) { + playerState = State_Skid; + isSkidding = true; + } else { + playerState = holdingRun ? State_Run : State_Walk; + } + } + if (bPlayerOnGround && !isSkidding) nDirModY = 1; + fPlayerVelX += -addSpeed * fElapsedTime; + groundFriction = 2.0f; + } + if(GetKeyState(KEY_RIGHT) && playerState != State_Crouch){ + hitDirKey = true; + bool isSkidding = false; + if (playerState == State_Idle || playerState == State_Walk || playerState == State_Run || playerState == State_Skid) { + if (fPlayerVelX < 0) { + playerState = State_Skid; + isSkidding = true; + } else { + playerState = holdingRun ? State_Run : State_Walk; + } + } + if (bPlayerOnGround && !isSkidding) nDirModY = 0; + fPlayerVelX += addSpeed * fElapsedTime; + groundFriction = 2.0f; + } + if (!hitDirKey && (playerState == State_Walk || playerState == State_Run || playerState == State_Skid) && bPlayerOnGround) playerState = State_Idle; + if (playerState == State_Jump && bPlayerOnGround) playerState = State_Idle; + if ((GetKeyDownState(KEY_B) || GetKeyDownState(KEY_A)) && playerState != State_Crouch) { + if(bPlayerOnGround){ + playerState = State_Jump; + fPlayerVelY = -14.0f; + nDirModX = 1; + } + } + if (GetKeyDownState(KEY_SELECT)) { + //KillPlayer(false); + } + } else { + // go right + if (endingStage == 0 && bPlayerOnGround) { + fPlayerVelX = 7; + playerState = State_Run; + } + } + fPlayerVelY += 20.0f * fElapsedTime; + + if (bPlayerOnGround) { + fPlayerVelX += -groundFriction * fPlayerVelX * fElapsedTime; + if(fabs(fPlayerVelX) < 0.01f){ + fPlayerVelX = 0.0f; + } + } + + if (fPlayerVelX > 10.0f) fPlayerVelX = 10.0f; + if (fPlayerVelX < -10.0f) fPlayerVelX = -10.0f; + if (fPlayerVelY > 100.0f) fPlayerVelY = 100.0f; + if (fPlayerVelY < -100.0f) fPlayerVelY = -100.0f; + bPlayerOnGround = false; + for (int i = 0; i < 5; i++) { + float fNewPlayerPosX = fPlayerPosX + fPlayerVelX * fElapsedTime * .2f; + float fNewPlayerPosY = fPlayerPosY + fPlayerVelY * fElapsedTime * .2f; + if (fNewPlayerPosX < 0) fNewPlayerPosX = 0; + if (ending) { + if (fNewPlayerPosX >= nLevelWidth) { + fNewPlayerPosX = nLevelWidth; + if (endingStage == 0) endingStage++; + fPlayerVelX = 0; + } + } else { + if (fNewPlayerPosX >= nLevelWidth - 1) { + fNewPlayerPosX = nLevelWidth - 1; + } + } + + if (GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY + 0.0f) == 'o') + { SetTile('.', fNewPlayerPosX + 0.0f, fNewPlayerPosY + 0.0f); gems++; score += 100; } + if (GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY + 1.0f) == 'o') + { SetTile('.', fNewPlayerPosX + 0.0f, fNewPlayerPosY + 1.0f); gems++; score += 100; } + if (GetTile(fNewPlayerPosX + 1.0f, fNewPlayerPosY + 0.0f) == 'o') + { SetTile('.', fNewPlayerPosX + 1.0f, fNewPlayerPosY + 0.0f); gems++; score += 100; } + if (GetTile(fNewPlayerPosX + 1.0f, fNewPlayerPosY + 1.0f) == 'o') + { SetTile('.', fNewPlayerPosX + 1.0f, fNewPlayerPosY + 1.0f); gems++; score += 100; } + + if (GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY + 0.0f) == '8') + { SetTile('0', fNewPlayerPosX + 0.0f, fNewPlayerPosY + 0.0f); ending = true; endingStage = 0; fPlayerVelX = 0; } + if (GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY + 1.0f) == '8') + { SetTile('0', fNewPlayerPosX + 0.0f, fNewPlayerPosY + 1.0f); ending = true; endingStage = 0; fPlayerVelX = 0; } + if (GetTile(fNewPlayerPosX + 1.0f, fNewPlayerPosY + 0.0f) == '8') + { SetTile('0', fNewPlayerPosX + 1.0f, fNewPlayerPosY + 0.0f); ending = true; endingStage = 0; fPlayerVelX = 0; } + if (GetTile(fNewPlayerPosX + 1.0f, fNewPlayerPosY + 1.0f) == '8') + { SetTile('0', fNewPlayerPosX + 1.0f, fNewPlayerPosY + 1.0f); ending = true; endingStage = 0; fPlayerVelX = 0; } + + + //Collision + if(fPlayerVelX < 0){ + if (IsSolid(GetTile(fNewPlayerPosX + 0.0f, fPlayerPosY + 0.0f), DIR_LEFT) || + IsSolid(GetTile(fNewPlayerPosX + 0.0f, fPlayerPosY + 0.9f), DIR_LEFT)){ + fNewPlayerPosX = (int)fNewPlayerPosX + 1; + fPlayerVelX = 0; + } + } + else if (fPlayerVelX > 0) { + if (IsSolid(GetTile(fNewPlayerPosX + 1.0f, fPlayerPosY + 0.0f), DIR_RIGHT) || + IsSolid(GetTile(fNewPlayerPosX + 1.0f, fPlayerPosY + 0.9f), DIR_RIGHT)){ + fNewPlayerPosX = (int)fNewPlayerPosX; + fPlayerVelX = 0; + if (ending) { + if (endingStage == 0) endingStage++; // initializes the countdown etc + playerState = State_Crouch; + nDirModY = 1; + } + } + } + + if (fPlayerVelY < 0) { + char c1 = GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY), c2 = GetTile(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + bool s1 = IsSolid(c1, DIR_UP); + bool s2 = IsSolid(c2, DIR_UP); + if (s1 || s2){ + if (nDirModY) { + if (s2) { + SpawnBump(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + if (c2 == '?') { gems++; score += 100; SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); } + if (c2 == '^') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_Mushroom); } + if (c2 == 'Q') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_Flower); } + if (c2 == 'A') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_Time); } + if (c2 == 'L') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_LifeUp); } + if (c2 == 'E') { isOnOffSwitchOn ^= 1;} + c1 = GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY); c2 = GetTile(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + } + if (s1) { + SpawnBump(fNewPlayerPosX + 0.0f, fNewPlayerPosY); + if (c1 == '?') { gems++; score += 100; SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); } + if (c1 == '^') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_Mushroom); } + if (c1 == 'Q') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_Flower); } + if (c1 == 'A') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_Time); } + if (c1 == 'L') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_LifeUp); } + if (c1 == 'E' && c2 != 'E') { isOnOffSwitchOn ^= 1;} + c1 = GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY); c2 = GetTile(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + } + } + else { + if (s1) { + SpawnBump(fNewPlayerPosX + 0.0f, fNewPlayerPosY); + if (c1 == '?') { gems++; score += 100; SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); } + if (c1 == '^') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_Mushroom); } + if (c1 == 'Q') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_Flower); } + if (c1 == 'A') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_Time); } + if (c1 == 'L') { SetTile('U', fNewPlayerPosX + 0.0f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.0f, fNewPlayerPosY - .5f, Enemy_LifeUp); } + if (c1 == 'E') { isOnOffSwitchOn ^= 1;} + c1 = GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY); c2 = GetTile(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + } + if (s2) { + SpawnBump(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + if (c2 == '?') { gems++; score += 100; SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); } + if (c2 == '^') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_Mushroom); } + if (c2 == 'Q') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_Flower); } + if (c2 == 'A') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_Time); } + if (c2 == 'L') { SetTile('U', fNewPlayerPosX + 0.9f, fNewPlayerPosY); SpawnMushTypeRise(fNewPlayerPosX + 0.9f, fNewPlayerPosY - .5f, Enemy_LifeUp); } + if (c2 == 'E' && c1 != 'E') { isOnOffSwitchOn ^= 1;} + c1 = GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY); c2 = GetTile(fNewPlayerPosX + 0.9f, fNewPlayerPosY); + } + } + fNewPlayerPosY = (int)fNewPlayerPosY + 1; + fPlayerVelY = 0; + } + } + else if (fPlayerVelY > 0) { + if (IsSolid(GetTile(fNewPlayerPosX + 0.0f, fNewPlayerPosY+1), DIR_DOWN) || + IsSolid(GetTile(fNewPlayerPosX + 0.9f, fNewPlayerPosY+1), DIR_DOWN)){ + fNewPlayerPosY = (int)fNewPlayerPosY; + fPlayerVelY = 0; + bPlayerOnGround = true; + nDirModX = 0; + } + } + fPlayerPosX = fNewPlayerPosX; + fPlayerPosY = fNewPlayerPosY; + } + // update enemies + for (uint32_t i = 0; i < enemies.size(); i++) { + enemies.at(i)->Update(fElapsedTime); + } +begin_deleting_shit: + for (uint32_t i = 0; i < enemies.size(); i++) { + if (enemies.at(i)->markForRemoval) { + // here we have the mark for removal shit, remove + // and restart the loop (not most efficient but it will do! + enemies.erase(enemies.begin() + i); + goto begin_deleting_shit; + } + } + } + switch (playerState) { + case State_Idle: nDirModX = 0; break; + case State_Walk: { + int r = (int)(gameTimer * 48.f); // every second represents 48 ticks, caps at 24 (.5s) + r %= 24; + nDirModX = 2 + r / 8; + break; + } + case State_Run: { + int r = (int)(gameTimer * 24.f); // every second represents 24 ticks, caps at 6 (.25s) + r %= 6; + nDirModX = 2 + r / 2; + break; + } + case State_Jump: nDirModX = 1; break; + case State_Skid: nDirModX = 5; break; + case State_Dead: nDirModX = 6; break; + case State_Crouch: nDirModX = 7; break; + } + while (gameTimer > 2048) { + gameTimer -= 2048.f; + } + fCameraPosX = fPlayerPosX + .5f; + fCameraPosY = fPlayerPosY + .5f; + +} +void DrawTile(char sTileID, int x, int y, char sTileIDAbove, bool renderInInventory, int tileX, int tileY) { + //^QAS + switch(sTileID){ + case '.': break; + case '#':DrawImage(&tilesImage[2], 16, 16,x, y);break; + case 'o':DrawImage(&tilesImage[3], 16, 16,x, y);break; + case '?':DrawImage(&tilesImage[9], 16, 16,x, y);break; + case '^':DrawImage(&tilesImage[gameMode == Mode_Maker ? 41 : 9], 16, 16,x, y); break; + case 'Q':DrawImage(&tilesImage[gameMode == Mode_Maker ? 44 : 9], 16, 16,x, y); break; + case 'A':DrawImage(&tilesImage[gameMode == Mode_Maker ? 45 : 9], 16, 16,x, y); break; + case 'L':DrawImage(&tilesImage[gameMode == Mode_Maker ? 46 : 9], 16, 16,x, y); break; + case 'B':DrawImage(&tilesImage[8], 16, 16,x, y);break; + case 'G': { + if (sTileIDAbove == 'G') + DrawImage(&tilesImage[0], 16, 16,x, y); + else + DrawImage(&tilesImage[16], 16, 16,x, y); + break; + } + case 'P': { + if (sTileIDAbove == 'P') + DrawImage(&tilesImage[35], 16, 16,x, y); + else + DrawImage(&tilesImage[34], 16, 16,x, y); + break; + } + case 'D':DrawImage(&tilesImage[0], 16, 16,x, y);break; + case 'U':DrawImage(&tilesImage[1], 16, 16,x, y);break; + case '1':DrawImage(&tilesImage[18], 16, 16,x, y);break; + case '!':DrawImage(&tilesImage[19], 16, 16,x, y);break; + case '~':DrawImage(&tilesImage[20], 16, 16,x, y);break; + case '`':DrawImage(&tilesImage[21], 16, 16,x, y);break; + case '(':DrawImage(&tilesImage[4], 16, 16,x, y);break; + case ')':DrawImage(&tilesImage[5], 16, 16,x, y);break; + case '|': { + if (sTileIDAbove == '|') + DrawImage(&tilesImage[7], 16, 16,x, y); + else + DrawImage(&tilesImage[6], 16, 16,x, y); + break; + } + case 'S': + if (gameMode == Mode_Maker) { + DrawImage(&tilesImage[13], 16, 16,x, y);break; + } else return; + case '{':DrawImage(&tilesImage[12], 16, 16,x, y);break; + case '}':DrawImage(&tilesImage[10], 16, 16,x, y);break; + case '&':DrawImage(&tilesImage[11], 16, 16,x, y);break; + case '=':DrawImage(&tilesImage[24], 16, 16,x, y);break; + case '>':DrawImage(&tilesImage[22], 16, 16,x, y);break; + case 'E':DrawImage(&tilesImage[isOnOffSwitchOn?25:26], 16, 16,x, y);break; + case 'F':DrawImage(&tilesImage[isOnOffSwitchOn?27:29], 16, 16,x, y);break; + case 'H':DrawImage(&tilesImage[isOnOffSwitchOn?30:28], 16, 16,x, y);break; + case '0':DrawImage(&tilesImage[52], 16, 16,x, y);break; + case '8':{ + // Draw the end marker + int frame = (int)(gameTimer * 8) % 4; + DrawImage(&tilesImage[48 + frame], 16, 16, x, y); + break; + } + case 'W': { + // spawn flower + if (renderInInventory || gameMode == Mode_Maker) { + DrawImage(&tilesImage[36], 16, 16,x, y); + } else { + Enemy mush; + mush.type = Enemy_Flower; + mush.posX = tileX; mush.posY = tileY; mush.homeX = 0; mush.homeY = 0; mush.mushroom.risingTimer = 0.0f; + SpawnEnemy(mush); SetTile('.', tileX, tileY); DrawTile('.', x, y, sTileIDAbove, renderInInventory); + } + break; + } + case 'X': { + // spawn life up + if (renderInInventory || gameMode == Mode_Maker) { + DrawImage(&tilesImage[38], 16, 16,x, y); + } else { + Enemy mush; + mush.type = Enemy_LifeUp; + mush.posX = tileX; mush.posY = tileY; mush.homeX = 0; mush.homeY = 0; mush.mushroom.risingTimer = 0.0f; + SpawnEnemy(mush); SetTile('.', tileX, tileY); DrawTile('.', x, y, sTileIDAbove, renderInInventory); + } + break; + } + case 'T': { + // spawn extra clock? + if (renderInInventory || gameMode == Mode_Maker) { + DrawImage(&tilesImage[37], 16, 16,x, y); + } else { + Enemy mush; + mush.type = Enemy_Time; + mush.posX = tileX; mush.posY = tileY; mush.homeX = 0; mush.homeY = 0; mush.mushroom.risingTimer = 0.0f; + SpawnEnemy(mush); SetTile('.', tileX, tileY); DrawTile('.', x, y, sTileIDAbove, renderInInventory); + } + break; + } + case 'M': { + // spawn mushroom? + if (renderInInventory || gameMode == Mode_Maker) { + DrawImage(&tilesImage[33], 16, 16,x, y); + } else { + Enemy mush; + mush.type = Enemy_Mushroom; + mush.posX = tileX; mush.posY = tileY; mush.homeX = 0; mush.homeY = 0; mush.mushroom.risingTimer = 0.0f; + SpawnEnemy(mush); SetTile('.', tileX, tileY); DrawTile('.', x, y, sTileIDAbove, renderInInventory); + } + break; + } + default: DrawImage(&tilesImage[63], 16, 16,x, y);break; + //FillRectangle(RGBA16(0, 12, 31, 1), x, y, 16, 16); + //break; + } +} + +bool isInEraseMode = false; +bool isDrawing = false; +bool multigrabMode = false; // unused, todo +void Game::Draw() { + + //Draw Level + int nTileWidth = 16; + int nTileHeight = 16; + int nVisibleTilesX = SCREEN_WIDTH / nTileWidth; + int nVisibleTilesY = SCREEN_HEIGHT/nTileHeight; + + float fOffsetX = fCameraPosX - (float)nVisibleTilesX / 2.0f; + float fOffsetY = fCameraPosY - (float)nVisibleTilesY / 2.0f; + + if(fOffsetX <= 0.0f) fOffsetX = 0.0f; + if(fOffsetY <= 0.0f) fOffsetY = 0.0f; + if(fOffsetX > (float)(nLevelWidth - nVisibleTilesX)) fOffsetX = nLevelWidth - nVisibleTilesX; + if(fOffsetY > (float)(nLevelHeight- nVisibleTilesY)) fOffsetY = nLevelHeight- nVisibleTilesY; + + float fTileOffsetX = (fOffsetX - (int)fOffsetX) * nTileWidth; + float fTileOffsetY = (fOffsetY - (int)fOffsetY) * nTileHeight; + + + for(int x = 0; x <= nVisibleTilesX; x++){ + for(int y = 0; y <= nVisibleTilesY; y++){ + int tileX = floorf((float)x + fOffsetX), tileY = floorf((float)y+fOffsetY); + char sTileID = GetTile(tileX, tileY); + char sTileIDAbove = GetTile(tileX, tileY - 1); + int BumpedBlockDrawY = 0; + if (tileX == BlockBumpedX && tileY == BlockBumpedY) { + BumpedBlockDrawY = (int)(sinf(BlockBumpTimer * 12.f) * -8.f); + } + bool shouldDraw = true; + if (gameMode == Mode_Maker) + { + Rectangle r1 = { draggedRectX1, draggedRectY1, draggedRectX2 - draggedRectX1 + 1, draggedRectY2 - draggedRectY1 + 1 }; + Point p = { tileX, tileY }; + shouldDraw = !isDraggingStuff || !RectangleContains(r1,p) || isInCopyMode; + } + if (shouldDraw) + DrawTile(sTileID, x*nTileWidth-fTileOffsetX, y*nTileHeight-fTileOffsetY + BumpedBlockDrawY, sTileIDAbove, false, tileX, tileY); + } + } + + if (multigrabMode) { + int px1 = (draggedRectX1 - fOffsetX) * nLevelWidth; + int py1 = (draggedRectY1 - fOffsetY) * nLevelWidth; + int px2 = (draggedRectX2 - fOffsetX) * nLevelWidth; + int py2 = (draggedRectY2 - fOffsetY) * nLevelWidth; + DrawRectangle(YELLOW, px1, py1, px2, py2); + } + + // draw the dragged tiles? + if (isDraggingStuff) { + for(int x = draggedRectX1; x <= draggedRectX2; x++){ + for(int y = draggedRectY1; y <= draggedRectY2; y++){ + int posX = ((float)x + (float)worldDragPosX / (float)nTileWidth - (float)draggedRectX1 - fOffsetX) * nTileWidth; + int posY = ((float)y + (float)worldDragPosY / (float)nTileWidth - (float)draggedRectY1 - fOffsetY) * nTileHeight; + DrawTile(GetTile(x, y), posX, posY, '.', false, x, y); + } + } + } + + bool doDisplayChar = true; + if (stunTimer > 0) { + doDisplayChar = GlobalTimer % 2; + } + if (doDisplayChar) { + if (nDirModY) + DrawImageFlippedH(&playrImage[nDirModX], nTileWidth, nTileHeight, (fPlayerPosX - fOffsetX)*nTileWidth, (fPlayerPosY - fOffsetY)*nTileHeight); + else + DrawImage(&playrImage[nDirModX], nTileWidth, nTileHeight, (fPlayerPosX - fOffsetX)*nTileWidth, (fPlayerPosY - fOffsetY)*nTileHeight); + } + for (uint32_t i = 0; i < enemies.size(); i++) { + enemies.at(i)->Draw(fOffsetX, fOffsetY); + } +} +bool hasInventoryOpen = false; +bool hasRightMenuOpen = false; +bool hasClickedPreviouslyMaker[15]; + +char hotbarSlots[8]; +int inventoryHotbarSelectedIdx = 0; +int hotbarSlotPage = 0; + +#define HOTBAR_SLOT_PAGE_COUNT 3 +char hotbarSlotPages[] = //{ + //"#o?^BG{}" + //"P()+|S&=" + //"EFH....." +//}; +"#oS8BG{}" +"P(?MTWX)" +"|&=EFH.."; + +extern bool isFileSystemEnabled; +void EmptyFunctionForInfoboxes(bool t) {} + +bool hasShowedFatUnusableDlg = false; +void Game::Update() { + ClearScreen(RGBA16(1, 27, 31, 1)); + if (dialogShown) { + // TODO + dialogPosition -= dialogPosition / 2; // todo: make it independent of fps + if (dialogPosition <= 1) { + dialogPosition = 0; + } else { + //glPolyFmt(POLY_ALPHA(3)); + //FillRectangle(BLACK, 0, 0, 256, 192); + //glPolyFmt(POLY_ALPHA(31)); + } + } else { + // go back down + if (dialogPosition == 0) dialogPosition = 1; + dialogPosition *= 2; + if (dialogPosition > 192) + dialogPosition = 192; + } + if (dialogShown) goto drawDialogAndReturn; // pause the game + + // + { + float fElapsedTime = 0.0166667f; + if (gameMode != Mode_Maker) UpdateGameLogic(fElapsedTime); + Draw(); + + switch (gameMode) { + case Mode_Maker: { + Point pTouch = { touch.px, touch.py }; + bool canTouchLevel = true; + if (hasInventoryOpen) { + Rectangle r = { 220, 5, 32, 16 }; + u16 color = 0xffff; + bool click = false; + click = RectangleContains(r, pTouch); + if (click) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + } + DrawImageColored(&lrArrowImage[1], r.width, r.height, r.x, r.y, 0, color); + if (hasClickedPreviouslyMaker[0] && !click) { + hasInventoryOpen = false; + } + hasClickedPreviouslyMaker[0] = click; + + for (int i = 0; i < 9; i++) { + Rectangle r = { 2 + i * 24, 1, 24, 28 }; + u16 color = 0xffff; + click = RectangleContains(r, pTouch); + if (click) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + } + // draw inventory slot shit + char c; + if (i < 8) c = hotbarSlots[i]; else c = '>'; + if (inventoryHotbarSelectedIdx == i) { + DrawImageColored(&itemSImage[0], r.width, r.height, r.x, r.y, 0, color); + } else { + DrawImageColored(&itemImage[0], r.width, r.height, r.x, r.y, 0, color); + } + // draw the tile itself slightly lower and to the right + DrawTile(c, r.x + 4, r.y + 4); + if (hasClickedPreviouslyMaker[i+1] && !click) { + if (i < 8) inventoryHotbarSelectedIdx = i; else { + hotbarSlotPage++; + if (hotbarSlotPage >= HOTBAR_SLOT_PAGE_COUNT) { + hotbarSlotPage = 0; + } + memcpy(hotbarSlots, 8 * hotbarSlotPage + hotbarSlotPages, 8); + } + } + hasClickedPreviouslyMaker[i+1] = click; + } + } else { + Rectangle r = { 0, 5, 32, 16 }; + u16 color = 0xffff; + bool click = false; + click = RectangleContains(r, pTouch); + if (click) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + } + DrawImageColored(&lrArrowImage[0], r.width, r.height, r.x, r.y, 0, color); + if (hasClickedPreviouslyMaker[0] && !click) { + hasInventoryOpen = true; + } + hasClickedPreviouslyMaker[0] = click; + } + if (hasRightMenuOpen) { + Rectangle r = { 200, 25, 32, 16 }; + u16 color = 0xffff; + bool click = false; + click = RectangleContains(r, pTouch); + if (click) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + } + DrawImageColored(&lrArrowImage[0], r.width, r.height, r.x, r.y, 0, color); + if (hasClickedPreviouslyMaker[10] && !click) { + hasRightMenuOpen = false; + } + hasClickedPreviouslyMaker[10] = click; + + r = { 256 - 34, 23, 34, 70 }; + FillRectangle(RGBA16(0x1A, 0x1A, 0x1B, 1), r.x, r.y, r.width, r.height); + if (RectangleContains(r, pTouch)) { + canTouchLevel = false; + } + r = { 226, 26, 28, 30 }; + color = 0xffff; + click = false; + if (RectangleContains(r, pTouch)) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + click = true; + } + DrawImageColored(&resetImage[0], r.width, r.height, r.x, r.y, 0, color); + if (!click && hasClickedPreviouslyMaker[11]) { + //LogMsg("Tried to reset"); + ShowDialog(ResetLevel, "Yes", "No", "Do you really want to", "reset this level? You will", "lose all the progress you've made."); + } + hasClickedPreviouslyMaker[11] = click; + r = { 226, 60, 28, 30 }; + color = 0xffff; + click = false; + if (RectangleContains(r, pTouch)) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + click = true; + } + DrawImageColored(&eraseImage[0], r.width, r.height, r.x, r.y, 0, color); + if (!click && hasClickedPreviouslyMaker[12]) { + // too bad we wont add dialog yet + isInEraseMode ^= 1; + } + hasClickedPreviouslyMaker[12] = click; + } else { + Rectangle r = { 230, 25, 32, 16 }; + u16 color = 0xffff; + bool click = false; + click = RectangleContains(r, pTouch); + if (click) { + color &= 0xBDEF; // 127,127,127 + canTouchLevel = false; + } + DrawImageColored(&lrArrowImage[1], r.width, r.height, r.x, r.y, 0, color); + if (hasClickedPreviouslyMaker[10] && !click) { + hasRightMenuOpen = true; + } + hasClickedPreviouslyMaker[10] = click; + } + if (isInEraseMode) isInCopyMode = false; + /**/ if (isInEraseMode) DrawImage(&ermodImage[0], 64, 16, 0, hasInventoryOpen ? 25 : 0); + else if (isInCopyMode) DrawImage(&cpmodImage[0], 64, 16, 0, hasInventoryOpen ? 25 : 0); + if (GetKeyDownState(KEY_START)) { + gameMode = Mode_Game; + DoLevelInitStuff(); + } + if (GetKeyDownState(KEY_SELECT)) { + gameMode = Mode_Game; + memcpy(sLevelBeforePlay, sLevel, nLevelHeight * nLevelWidth); + } + + int nTileWidth = 16; + int nTileHeight = 16; + int nVisibleTilesX = SCREEN_WIDTH / nTileWidth; + int nVisibleTilesY = SCREEN_HEIGHT/nTileHeight; + if (canTouchLevel) { + float fOffsetX = fCameraPosX - (float)nVisibleTilesX / 2.0f; + float fOffsetY = fCameraPosY - (float)nVisibleTilesY / 2.0f; + + if(fOffsetX <= 0.0f) fOffsetX = 0.0f; + if(fOffsetY <= 0.0f) fOffsetY = 0.0f; + if(fOffsetX > (float)(nLevelWidth - nVisibleTilesX)) fOffsetX = nLevelWidth - nVisibleTilesX; + if(fOffsetY > (float)(nLevelHeight- nVisibleTilesY)) fOffsetY = nLevelHeight- nVisibleTilesY; + + int worldPosX = pTouch.x + fOffsetX * 16; + int worldPosY = pTouch.y + fOffsetY * 16; + int tilePosX = worldPosX / 16; + int tilePosY = worldPosY / 16; + + if (pTouch.x != 0 && pTouch.y != 0) { // has touched screen + if (isInEraseMode) { + SetTile('.', tilePosX, tilePosY); + isDraggingStuff = false; + } else if (multigrabMode) { + if (isDrawing) { + draggedRectX2 = tilePosX; + draggedRectY2 = tilePosY; + } else { + if (draggedRectX1 != -1) { + isDraggingStuff = true; + worldDragPosX = draggedRectX1 * 16; + worldDragPosY = draggedRectY1 * 16; + } else { + isDrawing = true; + draggedRectX1 = tilePosX; + draggedRectY1 = tilePosY; + } + } + } else { + if (isDraggingStuff) { + worldDragPosX += worldPosX - lastWorldTouchPosX; + worldDragPosY += worldPosY - lastWorldTouchPosY; + } else { + char c = hotbarSlots[inventoryHotbarSelectedIdx]; + if (c != '.') { + if (GetTile(tilePosX, tilePosY) == '.' || isDrawing) { + SetTile(c, tilePosX, tilePosY); + isDrawing = true; + } else { + // drag + isDraggingStuff = true; + draggedRectX1 = tilePosX; + draggedRectX2 = tilePosX; + draggedRectY1 = tilePosY; + draggedRectY2 = tilePosY; + + worldDragPosX = tilePosX * 16; + worldDragPosY = tilePosY * 16; + } + } + } + } + } else { + isDrawing = false; + if (isDraggingStuff) { + isDraggingStuff = false; + /* + // release? + bool goRightToLeft = worldDragPosX > draggedRectX1; + bool goDownToUp = worldDragPosY > draggedRectY1; + + + if (goDownToUp) { + if (goRightToLeft) { + for (int i = draggedRectX2; i >= draggedRectX1; i--) { + for (int j = draggedRectY2; j >= draggedRectY1; j--) { + int offsetX = (int)roundf(worldDragPosX / 16.f) + i - draggedRectX1; + int offsetY = (int)roundf(worldDragPosY / 16.f) + j - draggedRectY1; + char c = GetTile(i, j); + SetTile('.', i, j); + SetTile(c, offsetX, offsetY); + } + } + } else { + for (int i = draggedRectX2; i >= draggedRectX1; i--) { + for (int j = draggedRectY1; j <= draggedRectY1; j++) { + int offsetX = (int)roundf(worldDragPosX / 16.f) + i - draggedRectX1; + int offsetY = (int)roundf(worldDragPosY / 16.f) + j - draggedRectY1; + char c = GetTile(i, j); + SetTile('.', i, j); + SetTile(c, offsetX, offsetY); + } + } + } + } else { + if (goRightToLeft) { + for (int i = draggedRectX1; i <= draggedRectX2; i++) { + for (int j = draggedRectY2; j >= draggedRectY1; j--) { + int offsetX = (int)roundf(worldDragPosX / 16.f) + i - draggedRectX1; + int offsetY = (int)roundf(worldDragPosY / 16.f) + j - draggedRectY1; + char c = GetTile(i, j); + SetTile('.', i, j); + SetTile(c, offsetX, offsetY); + } + } + } else { + for (int i = draggedRectX1; i <= draggedRectX2; i++) { + for (int j = draggedRectY1; j <= draggedRectY1; j++) { + int offsetX = (int)roundf(worldDragPosX / 16.f) + i - draggedRectX1; + int offsetY = (int)roundf(worldDragPosY / 16.f) + j - draggedRectY1; + char c = GetTile(i, j); + SetTile('.', i, j); + SetTile(c, offsetX, offsetY); + } + } + } + }*/ + int i = draggedRectX1; + int j = draggedRectY1; + int offsetX = (int)roundf(worldDragPosX / 16.f) + i - draggedRectX1; + int offsetY = (int)roundf(worldDragPosY / 16.f) + j - draggedRectY1; + char c = GetTile(i, j); + char cDest = GetTile(offsetX, offsetY); + if (!isInCopyMode) SetTile('.', i, j); + switch (cDest) { + // here we do special actions, for example, placing + // a mushroom on top of a ? block + case '?': + if (c == 'M') c = '^'; // mushroom + if (c == 'T') c = 'A'; // extra clock + if (c == 'W') c = 'Q'; // flower + if (c == 'X') c = 'L'; // life up + break; // todo + } + SetTile(c, offsetX, offsetY); + + draggedRectX1 = -1; + draggedRectX2 = -1; + draggedRectY1 = -1; + draggedRectY2 = -1; + + worldDragPosX = 0; + worldDragPosY = 0; + } + } + lastWorldTouchPosX = worldPosX; + lastWorldTouchPosY = worldPosY; + } + + fCameraPosY = nVisibleTilesY / 2.f; + float moveSpeed = 10; + bool b = GetKeyState(KEY_Y); + if (b) moveSpeed *= 2; + bool hitDirKey = false; + if (GetKeyState(KEY_UP)) { + fPlayerPosY -= moveSpeed * fElapsedTime; + if (fPlayerPosY < 0) fPlayerPosY = 0; + hitDirKey = true; + } + if (GetKeyState(KEY_DOWN)) { + fPlayerPosY += moveSpeed * fElapsedTime; + if (fPlayerPosY >= nLevelHeight) fPlayerPosY = nLevelHeight - 1; + } + if (GetKeyState(KEY_LEFT)) { + fPlayerPosX -= moveSpeed * fElapsedTime; + if (fPlayerPosX < 0) fPlayerPosX = 0; + while (fPlayerPosX < fCameraPosX - 6) { + fCameraPosX -= moveSpeed * fElapsedTime; + } + hitDirKey = true; + } + if (GetKeyState(KEY_RIGHT)) { + fPlayerPosX += moveSpeed * fElapsedTime; + if (fPlayerPosX >= nLevelWidth - 1) fPlayerPosX = nLevelWidth - 1; + while (fPlayerPosX > fCameraPosX + 6) { + fCameraPosX += moveSpeed * fElapsedTime; + } + hitDirKey = true; + } + if (GetKeyDownState(KEY_L)) { + isInEraseMode ^= 1; + isInCopyMode = 0; + } + if (GetKeyDownState(KEY_R)) { + isInCopyMode ^= 1; + isInEraseMode = 0; + } + if (GetKeyDownState(KEY_Y) && !hitDirKey) { + // call player + fPlayerPosX = fCameraPosX; + fPlayerPosY = fCameraPosY; + } + + if (playerState == State_Dead && fPlayerPosY > nLevelHeight) { + fPlayerPosX = fCameraPosX; + fPlayerPosY = fCameraPosY; + } + playerState = State_Idle; + + break; // todo + } + case Mode_Title: { + //DrawString((SCREEN_WIDTH - 20 * 6) / 2, 40, WHITE, "GAME MAKER PROTOTYPE", 0); + DrawImage(logoImage, 256, 32, (SCREEN_WIDTH - 192) / 2, 40); + if (hasPressedLROrStart) { + DrawString((SCREEN_WIDTH - 26 * 6) / 2, 100, WHITE, "Touch the buttons to play!", 0); + Rectangle r[2] = { { (SCREEN_WIDTH - 96) / 2, 110, 48, 36}, {(SCREEN_WIDTH - 96) / 2 + 48, 110, 48, 36}}; + Point pTouch = { touch.px, touch.py }; + bool clicked[2] = { RectangleContains(r[0], pTouch), RectangleContains(r[1], pTouch)}; + const char* texts[2] = { makeText, playText }; + for (int i = 0; i < 2; i++) { + DrawImage(&cbordImage[!clicked[i]], 48, 36, r[i].x, r[i].y); + DrawString(r[i].x + 25 - strlen(texts[i]) * 3, r[i].y + 21, BLACK, texts[i], 0); + DrawString(r[i].x + 24 - strlen(texts[i]) * 3, r[i].y + 20, WHITE, texts[i], 0); + } + if (!clicked[0] && hasClickedPreviously[0]) { + hasPressedLROrStart = false; + //gameMode = Mode_Maker; + SetToMakerMode(); + LoadLevelToMem(level_1, level_1_width, level_1_height); + canEditLevel = true; + } + if (!clicked[1] && hasClickedPreviously[1]) { + hasPressedLROrStart = false; + gameMode = Mode_Game; + } + memcpy(hasClickedPreviously, clicked, sizeof(clicked)); + } else { + DrawString((SCREEN_WIDTH - 13 * 6) / 2, 140, WHITE, "Press [L]/[R]", 0); + if (GetKeyState(KEY_L) && GetKeyState(KEY_R)) { + hasPressedLROrStart = true; + } + } + case Mode_Game: { + // draw game UI? + char ch[100]; + memset(ch, 0, 100); + sprintf(ch, "%09d \xb%03d", score, (int)inGameTime); + DrawString(SCREEN_WIDTH - 6 - 6 * strlen(ch), 5, WHITE, ch, 0); + memset(ch, 0, 100); + sprintf(ch, "\x9x%02d", gems); + DrawString(6, 5, WHITE, ch, 0); + + int hpBarWidth = 184, hpBarX = 36; + if (lastHP == 0) lastHP = hp; + else lastHP = (lastHP * 7.f + (float)hp) / 8.f; + int curHPWidth = (int)((float)lastHP * (float)hpBarWidth / (float)maxHP); + FillRectangle(RED & 0xBDEF, hpBarX, 15, hpBarWidth, 3); + FillRectangle(RED, hpBarX, 15, curHPWidth, 3); + + memset(ch, 0, 100); + sprintf(ch, "%d", 0); + DrawString(hpBarX - 3 - 6 * strlen(ch), 13, WHITE, ch, 0); + memset(ch, 0, 100); + sprintf(ch, "%d", maxHP); + DrawString(hpBarX + hpBarWidth + 3, 13, WHITE, ch, 0); + + break; // todo + } + } + } + if (doSetToMakerMode) { + doSetToMakerMode = false; + gameMode = Mode_Maker; + ResetEverything(); + } + } +drawDialogAndReturn: + if (dialogPosition < 191) DrawDialog(dialogShown); + + if (!hasShowedFatUnusableDlg && !isFileSystemEnabled) { + hasShowedFatUnusableDlg = true; + //ShowDialog(EmptyFunctionForInfoboxes, "OK", "OK", "The file system could not", "be initialized, you can't save", "levels."); + } + +} +void LoadLevelToMem(char* c, int w, int h) { + if (sLevel) delete[] sLevel; + if (sLevelBeforePlay) delete[] sLevelBeforePlay; + nLevelWidth = w; + nLevelHeight = h; + sLevel = new char[nLevelWidth * nLevelHeight]; + sLevelBeforePlay = new char[nLevelWidth * nLevelHeight]; + memcpy(sLevel, c, nLevelHeight * nLevelWidth); + memcpy(sLevelBeforePlay, c, nLevelHeight * nLevelWidth); +} +void DoLevelInitStuff() { + memcpy(sLevelBeforePlay, sLevel, nLevelHeight * nLevelWidth); + playerState = State_Idle; + int count = nLevelWidth * nLevelHeight; + fPlayerPosX = fPlayerPosY = fPlayerVelX = fPlayerVelY = 0; + for (int i = 0; i < count; i++) { + /* + if (sLevel[i] == '&') { + if (sLevel[i + nLevelWidth] == 'G') + sLevel[i + nLevelWidth] = '}'; + else + sLevel[i + nLevelWidth] = '{'; + } + */ + + if (sLevel[i] == 'S') { + fPlayerPosX = i % nLevelWidth; + fPlayerPosY = i / nLevelWidth; + //sLevel[i] = '{'; + } + } + gems = 0; + score = 0; + inGameTime = maxTime; + hp = 1; + maxHP = 1; + inGameTime = 500; + gems = 0; + score = 0; + stunTimer = 0; + lastHP = 1; + ending = false; + endingStage = 0; +} +void Game::Init() { + LoadLevelToMem(level_1_old, level_1_width, level_1_height); + DoLevelInitStuff(); +} +void Game::LoadContent() { + LogMsg("Loading content"); + decompress(tilesBitmap, textureCacheBmp, LZ77); + tileSpriteID = glLoadTileSet(tilesImage, 16, 16, 128, 128, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_128, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 256, NULL, (u8*)textureCacheBmp); + decompress(characterBitmap, textureCacheBmp, LZ77); + plyrSpriteID = glLoadTileSet(playrImage, 16, 16, 128, 16, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_16, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 256, NULL, (u8*)textureCacheBmp); + decompress(clapperboardBitmap, textureCacheBmp, LZ77); + cbrdSpriteID = glLoadTileSet(cbordImage, 48, 36, 128, 64, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_64, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(itemselBitmap, textureCacheBmp, LZ77); + itemSelSpriteID = glLoadTileSet(itemSImage, 32,32,32,32, GL_RGBA, TEXTURE_SIZE_32, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(itemBitmap, textureCacheBmp, LZ77); + itemSpriteID = glLoadTileSet(itemImage, 32,32,32,32, GL_RGBA, TEXTURE_SIZE_32, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(lr_arrowsBitmap, textureCacheBmp, LZ77); + lrArSpriteID = glLoadTileSet(lrArrowImage, 32,16,32,32, GL_RGBA, TEXTURE_SIZE_32, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(undoBitmap, textureCacheBmp, LZ77); + undoSpriteID = glLoadTileSet(undoImage, 32,32,32,32, GL_RGBA, TEXTURE_SIZE_32, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(eraseBitmap, textureCacheBmp, LZ77); + eraseSpriteID = glLoadTileSet(eraseImage, 32,32,32,32, GL_RGBA, TEXTURE_SIZE_32, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(resetBitmap, textureCacheBmp, LZ77); + resetSpriteID = glLoadTileSet(resetImage, 32,32,32,32, GL_RGBA, TEXTURE_SIZE_32, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(erase_modeBitmap, textureCacheBmp, LZ77); + ermodSpriteID = glLoadTileSet(ermodImage,64,16,64,16, GL_RGBA, TEXTURE_SIZE_64, TEXTURE_SIZE_16, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(copy_modeBitmap, textureCacheBmp, LZ77); + cpmodSpriteID = glLoadTileSet(cpmodImage,64,16,64,16, GL_RGBA, TEXTURE_SIZE_64, TEXTURE_SIZE_16, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(dialog_bgBitmap, textureCacheBmp, LZ77); + dlgBgSpriteID = glLoadTileSet(dlgBgImage,256,256,256,256, GL_RGBA, TEXTURE_SIZE_256, TEXTURE_SIZE_256, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(dialogbtnBitmap, textureCacheBmp, LZ77); + dlgBtnSpriteID = glLoadTileSet(dlgBtnImage,128,32,128,32, GL_RGBA, TEXTURE_SIZE_128, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + decompress(logoBitmap, textureCacheBmp, LZ77); + logoSpriteID = glLoadTileSet(logoImage,256,32,256,32, GL_RGBA, TEXTURE_SIZE_256, TEXTURE_SIZE_32, GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, 0, NULL, (u8*)textureCacheBmp); + + memcpy(hotbarSlots, hotbarSlotPages, 8); + + Enemy::CommonLoad(); +} +time_t currentTime; +void Title::Update(){ + DrawString((SCREEN_WIDTH - 20 * 6) / 2, 30, WHITE, "GAME MAKER PROTOTYPE", 0); + DrawString((SCREEN_WIDTH - 30 * 6) / 2, 90, WHITE, "Touch the Touch Screen to play", 0); + if ((touch.px != 0 || touch.py != 0) && !(prevTouch.px != 0 || prevTouch.py != 0)) { + LogMsg("Touch2 at x:%d, y:%d", touch.px, touch.py); + //mode = PlayMode::Mode::Game; + } + char s[100]; + memset(s,0,100); + currentTime = time(nullptr); + auto m = gmtime(¤tTime); + strftime(s, 99, "TOD: %a, %d %b %Y at %H:%M:%S", m); + DrawString(3, 3, WHITE, s, 0); +} +void Title::Init() { + +} +void Title::LoadContent() { + +} \ No newline at end of file diff --git a/source/TestGame.hpp b/source/TestGame.hpp new file mode 100644 index 0000000..4b8e80e --- /dev/null +++ b/source/TestGame.hpp @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + Programmed by iProgramInCpp + + TestGame module +---------------------------------------------------------------------------------*/ +#include "EngineDec.h" +#include "Utils.hpp" + +#ifndef TESTGAME_HPP +#define TESTGAME_HPP + +//extern short tiles[128*128]; +//extern short character[128*16]; +//extern short clapperboard[128*64]; +extern glImage tilesImage[64]; +extern int BlockBumpedX, BlockBumpedY; +extern float fPlayerPosX, fPlayerPosY; +extern float maxTime; +extern int gems, score; +extern float inGameTime; +extern int nLevelWidth, nLevelHeight; +namespace Game { + void UpdateGameLogic(float fElapsedTime); + void Update(); + void Draw(); + void Init(); + void LoadContent(); +}; +namespace Title { + void Update(); + void Init(); + void LoadContent(); +}; +void DrawTile(char sTileID, int x, int y, char sTileIDAbove = '.', bool renderInInventory = true, int tileX = 0, int tileY = 0); +#define DIR_UP 0x01 +#define DIR_DOWN 0x02 +#define DIR_LEFT 0x04 +#define DIR_RIGHT 0x08 +bool IsSolid(char c, int directions); +char GetTile(int x, int y); +void SetTile(char c, int x, int y); +void IncreaseMaxHP(); +void DamagePlayer(); +void HealPlayer(); +typedef void DialogResultFunction(bool); // the bool represents saidYes +void ShowDialog(DialogResultFunction* f, const char* dialogYes, const char* dialogNo, const char* dlgRow1, const char* dlgRow2 = nullptr, const char* dlgRow3 = nullptr); +#endif//TESTGAME_HPP \ No newline at end of file diff --git a/source/Typeface.h b/source/Typeface.h new file mode 100644 index 0000000..1eb4775 --- /dev/null +++ b/source/Typeface.h @@ -0,0 +1,259 @@ +const char MainFont[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, + 0x00, 0x18, 0x3C, 0x18, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, + 0x00, 0x18, 0x24, 0x18, 0x00, + 0x1F, 0x0F, 0x3E, 0xCC, 0x08, //0xFF, 0xE7, 0xDB, 0xE7, 0xFF, + 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, + 0x40, 0x7F, 0x05, 0x05, 0x07, + 0x40, 0x7F, 0x05, 0x25, 0x3F, + 0x7E, 0x99, 0xA5, 0xA5, 0x7E, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, + 0x14, 0x22, 0x7F, 0x22, 0x14, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, + 0x06, 0x09, 0x7F, 0x01, 0x7F, + 0x00, 0x66, 0x89, 0x95, 0x6A, + 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, + 0x08, 0x04, 0x7E, 0x04, 0x08, + 0x10, 0x20, 0x7E, 0x20, 0x10, + 0x08, 0x08, 0x2A, 0x1C, 0x08, + 0x08, 0x1C, 0x2A, 0x08, 0x08, + 0x1E, 0x10, 0x10, 0x10, 0x10, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, + 0x30, 0x38, 0x3E, 0x38, 0x30, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, + 0x36, 0x49, 0x56, 0x20, 0x50, + 0x00, 0x08, 0x07, 0x03, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, + 0x08, 0x08, 0x3E, 0x08, 0x08, + 0x00, 0x80, 0x70, 0x30, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x60, 0x60, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, + 0x00, 0x42, 0x7F, 0x40, 0x00, + 0x72, 0x49, 0x49, 0x49, 0x46, + 0x21, 0x41, 0x49, 0x4D, 0x33, + 0x18, 0x14, 0x12, 0x7F, 0x10, + 0x27, 0x45, 0x45, 0x45, 0x39, + 0x3C, 0x4A, 0x49, 0x49, 0x31, + 0x41, 0x21, 0x11, 0x09, 0x07, + 0x36, 0x49, 0x49, 0x49, 0x36, + 0x46, 0x49, 0x49, 0x29, 0x1E, + 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x00, 0x41, 0x22, 0x14, 0x08, + 0x02, 0x01, 0x59, 0x09, 0x06, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, + 0x7C, 0x12, 0x11, 0x12, 0x7C, + 0x7F, 0x49, 0x49, 0x49, 0x36, + 0x3E, 0x41, 0x41, 0x41, 0x22, + 0x7F, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x49, 0x49, 0x49, 0x41, + 0x7F, 0x09, 0x09, 0x09, 0x01, + 0x3E, 0x41, 0x41, 0x51, 0x73, + 0x7F, 0x08, 0x08, 0x08, 0x7F, + 0x00, 0x41, 0x7F, 0x41, 0x00, + 0x20, 0x40, 0x41, 0x3F, 0x01, + 0x7F, 0x08, 0x14, 0x22, 0x41, + 0x7F, 0x40, 0x40, 0x40, 0x40, + 0x7F, 0x02, 0x1C, 0x02, 0x7F, + 0x7F, 0x04, 0x08, 0x10, 0x7F, + 0x3E, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x09, 0x09, 0x09, 0x06, + 0x3E, 0x41, 0x51, 0x21, 0x5E, + 0x7F, 0x09, 0x19, 0x29, 0x46, + 0x26, 0x49, 0x49, 0x49, 0x32, + 0x03, 0x01, 0x7F, 0x01, 0x03, + 0x3F, 0x40, 0x40, 0x40, 0x3F, + 0x1F, 0x20, 0x40, 0x20, 0x1F, + 0x3F, 0x40, 0x38, 0x40, 0x3F, + 0x63, 0x14, 0x08, 0x14, 0x63, + 0x03, 0x04, 0x78, 0x04, 0x03, + 0x61, 0x59, 0x49, 0x4D, 0x43, + 0x00, 0x7F, 0x41, 0x41, 0x41, + 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, + 0x04, 0x02, 0x01, 0x02, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x03, 0x07, 0x08, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, + 0x7F, 0x28, 0x44, 0x44, 0x38, + 0x38, 0x44, 0x44, 0x44, 0x28, + 0x38, 0x44, 0x44, 0x28, 0x7F, + 0x38, 0x54, 0x54, 0x54, 0x18, + 0x00, 0x08, 0x7E, 0x09, 0x02, + 0x18, 0xA4, 0xA4, 0x9C, 0x78, + 0x7F, 0x08, 0x04, 0x04, 0x78, + 0x00, 0x44, 0x7D, 0x40, 0x00, + 0x20, 0x40, 0x40, 0x3D, 0x00, + 0x7F, 0x10, 0x28, 0x44, 0x00, + 0x00, 0x41, 0x7F, 0x40, 0x00, + 0x7C, 0x04, 0x78, 0x04, 0x78, + 0x7C, 0x08, 0x04, 0x04, 0x78, + 0x38, 0x44, 0x44, 0x44, 0x38, + 0xFC, 0x18, 0x24, 0x24, 0x18, + 0x18, 0x24, 0x24, 0x18, 0xFC, + 0x7C, 0x08, 0x04, 0x04, 0x08, + 0x48, 0x54, 0x54, 0x54, 0x24, + 0x04, 0x04, 0x3F, 0x44, 0x24, + 0x3C, 0x40, 0x40, 0x20, 0x7C, + 0x1C, 0x20, 0x40, 0x20, 0x1C, + 0x3C, 0x40, 0x30, 0x40, 0x3C, + 0x44, 0x28, 0x10, 0x28, 0x44, + 0x4C, 0x90, 0x90, 0x90, 0x7C, + 0x44, 0x64, 0x54, 0x4C, 0x44, + 0x00, 0x08, 0x36, 0x41, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, + 0x3C, 0x26, 0x23, 0x26, 0x3C, + 0x1E, 0xA1, 0xA1, 0x61, 0x12, + 0x3A, 0x40, 0x40, 0x20, 0x7A, + 0x38, 0x54, 0x54, 0x55, 0x59, + 0x21, 0x55, 0x55, 0x79, 0x41, + 0x22, 0x54, 0x54, 0x78, 0x42, + 0x21, 0x55, 0x54, 0x78, 0x40, + 0x20, 0x54, 0x55, 0x79, 0x40, + 0x0C, 0x1E, 0x52, 0x72, 0x12, + 0x39, 0x55, 0x55, 0x55, 0x59, + 0x39, 0x54, 0x54, 0x54, 0x59, + 0x39, 0x55, 0x54, 0x54, 0x58, + 0x00, 0x00, 0x45, 0x7C, 0x41, + 0x00, 0x02, 0x45, 0x7D, 0x42, + 0x00, 0x01, 0x45, 0x7C, 0x40, + 0x7D, 0x12, 0x11, 0x12, 0x7D, + 0xF0, 0x28, 0x25, 0x28, 0xF0, + 0x7C, 0x54, 0x55, 0x45, 0x00, + 0x20, 0x54, 0x54, 0x7C, 0x54, + 0x7C, 0x0A, 0x09, 0x7F, 0x49, + 0x32, 0x49, 0x49, 0x49, 0x32, + 0x3A, 0x44, 0x44, 0x44, 0x3A, + 0x32, 0x4A, 0x48, 0x48, 0x30, + 0x3A, 0x41, 0x41, 0x21, 0x7A, + 0x3A, 0x42, 0x40, 0x20, 0x78, + 0x00, 0x9D, 0xA0, 0xA0, 0x7D, + 0x3D, 0x42, 0x42, 0x42, 0x3D, + 0x3D, 0x40, 0x40, 0x40, 0x3D, + 0x3C, 0x24, 0xFF, 0x24, 0x24, + 0x48, 0x7E, 0x49, 0x43, 0x66, + 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, + 0xFF, 0x09, 0x29, 0xF6, 0x20, + 0xC0, 0x88, 0x7E, 0x09, 0x03, + 0x20, 0x54, 0x54, 0x79, 0x41, + 0x00, 0x00, 0x44, 0x7D, 0x41, + 0x30, 0x48, 0x48, 0x4A, 0x32, + 0x38, 0x40, 0x40, 0x22, 0x7A, + 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, + 0x26, 0x29, 0x29, 0x2F, 0x28, + 0x26, 0x29, 0x29, 0x29, 0x26, + 0x30, 0x48, 0x4D, 0x40, 0x20, + 0x38, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, + 0x2F, 0x10, 0xC8, 0xAC, 0xBA, + 0x2F, 0x10, 0x28, 0x34, 0xFA, + 0x00, 0x00, 0x7B, 0x00, 0x00, + 0x08, 0x14, 0x2A, 0x14, 0x22, + 0x22, 0x14, 0x2A, 0x14, 0x08, + 0x55, 0x00, 0x55, 0x00, 0x55, + 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0xFF, 0x55, 0xFF, 0x55, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x10, 0x10, 0x10, 0xFF, 0x00, + 0x14, 0x14, 0x14, 0xFF, 0x00, + 0x10, 0x10, 0xFF, 0x00, 0xFF, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x14, 0x14, 0x14, 0xFC, 0x00, + 0x14, 0x14, 0xF7, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x14, 0x14, 0xF4, 0x04, 0xFC, + 0x14, 0x14, 0x17, 0x10, 0x1F, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, + 0x10, 0x10, 0x10, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0xF0, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0xFF, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x14, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, + 0x14, 0x14, 0x17, 0x10, 0x17, + 0x14, 0x14, 0xF4, 0x04, 0xF4, + 0x00, 0x00, 0xFF, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0xF7, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x17, 0x14, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0xF4, 0x14, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, + 0x00, 0x00, 0x00, 0xFC, 0x14, + 0x00, 0x00, 0xF0, 0x10, 0xF0, + 0x10, 0x10, 0xFF, 0x10, 0xFF, + 0x14, 0x14, 0x14, 0xFF, 0x14, + 0x10, 0x10, 0x10, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x38, 0x44, 0x44, 0x38, 0x44, + 0xFC, 0x4A, 0x4A, 0x4A, 0x34, + 0x7E, 0x02, 0x02, 0x06, 0x06, + 0x02, 0x7E, 0x02, 0x7E, 0x02, + 0x63, 0x55, 0x49, 0x41, 0x63, + 0x38, 0x44, 0x44, 0x3C, 0x04, + 0x40, 0x7E, 0x20, 0x1E, 0x20, + 0x06, 0x02, 0x7E, 0x02, 0x02, + 0x99, 0xA5, 0xE7, 0xA5, 0x99, + 0x1C, 0x2A, 0x49, 0x2A, 0x1C, + 0x4C, 0x72, 0x01, 0x72, 0x4C, + 0x30, 0x4A, 0x4D, 0x4D, 0x30, + 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, + 0x3E, 0x49, 0x49, 0x49, 0x00, + 0x7E, 0x01, 0x01, 0x01, 0x7E, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x44, 0x44, 0x5F, 0x44, 0x44, + 0x40, 0x51, 0x4A, 0x44, 0x40, + 0x40, 0x44, 0x4A, 0x51, 0x40, + 0x00, 0x00, 0xFF, 0x01, 0x03, + 0xE0, 0x80, 0xFF, 0x00, 0x00, + 0x08, 0x08, 0x6B, 0x6B, 0x08, + 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, + 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x00, + 0x30, 0x40, 0xFF, 0x01, 0x01, + 0x00, 0x1F, 0x01, 0x01, 0x1E, + 0x00, 0x19, 0x1D, 0x17, 0x12, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/source/Utils.cpp b/source/Utils.cpp new file mode 100644 index 0000000..4cfe62e --- /dev/null +++ b/source/Utils.cpp @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + Programmed by iProgramInCpp + + Utils module +---------------------------------------------------------------------------------*/ +#include "Utils.hpp" + +void LogMsg(const char* s, ...) { + + char c[10240]; + va_list v; + va_start(v, s); + memset(c,0,sizeof(c)); + vsprintf(c, s, v); + va_end(v); + puts(c); + +} \ No newline at end of file diff --git a/source/Utils.hpp b/source/Utils.hpp new file mode 100644 index 0000000..7310a03 --- /dev/null +++ b/source/Utils.hpp @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------- + GAME PROJECT + [ July 29, 2020 ] + Programmed by iProgramInCpp + + Utils module +---------------------------------------------------------------------------------*/ +#include +#include +#include +void LogMsg(const char* m, ...); \ No newline at end of file