diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..921ff89 --- /dev/null +++ b/Makefile @@ -0,0 +1,164 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# 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 := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source source/game source/platform +DATA := data/fonts data/images data/sounds data/wiimote +INCLUDES := source source/game source/platform + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) `freetype-config --cflags` +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lgrr `freetype-config --libs` -lpng -ljpeg -lfat -lz -lbz2 -lwiiuse -lbte -lasnd -logc -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) + +#--------------------------------------------------------------------------------- +# 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)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) + +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +INCLUDEDIR := $(foreach dir,$(LIBDIRS),$(dir $(wildcard $(dir)/include/*/))) +export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(INCLUDEDIR),-I$(dir)) \ + -I$(CURDIR)/include \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + $(foreach dir,$(PORTLIBS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +run: + wiiload $(TARGET).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .png extension +#--------------------------------------------------------------------------------- +%.png.o : %.png +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .ttf extension +#--------------------------------------------------------------------------------- +%.ttf.o : %.ttf +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .raw extension +#--------------------------------------------------------------------------------- +%.raw.o : %.raw +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/data/fonts/FreeSerif.ttf b/data/fonts/FreeSerif.ttf new file mode 100644 index 0000000..18c1109 Binary files /dev/null and b/data/fonts/FreeSerif.ttf differ diff --git a/data/fonts/xped.ttf b/data/fonts/xped.ttf new file mode 100644 index 0000000..2647206 Binary files /dev/null and b/data/fonts/xped.ttf differ diff --git a/data/images/armorbattle_blipbright.png b/data/images/armorbattle_blipbright.png new file mode 100644 index 0000000..17d39c4 Binary files /dev/null and b/data/images/armorbattle_blipbright.png differ diff --git a/data/images/armorbattle_blipdim.png b/data/images/armorbattle_blipdim.png new file mode 100644 index 0000000..b58f217 Binary files /dev/null and b/data/images/armorbattle_blipdim.png differ diff --git a/data/images/armorbattle_digits.png b/data/images/armorbattle_digits.png new file mode 100644 index 0000000..8edc9ac Binary files /dev/null and b/data/images/armorbattle_digits.png differ diff --git a/data/images/armorbattle_poweroff.png b/data/images/armorbattle_poweroff.png new file mode 100644 index 0000000..74046f0 Binary files /dev/null and b/data/images/armorbattle_poweroff.png differ diff --git a/data/images/armorbattle_poweron.png b/data/images/armorbattle_poweron.png new file mode 100644 index 0000000..e9f8009 Binary files /dev/null and b/data/images/armorbattle_poweron.png differ diff --git a/data/images/armorbattle_screen.png b/data/images/armorbattle_screen.png new file mode 100644 index 0000000..b0db88b Binary files /dev/null and b/data/images/armorbattle_screen.png differ diff --git a/data/images/autorace_aimcenter.png b/data/images/autorace_aimcenter.png new file mode 100644 index 0000000..a9069ba Binary files /dev/null and b/data/images/autorace_aimcenter.png differ diff --git a/data/images/autorace_aimleft.png b/data/images/autorace_aimleft.png new file mode 100644 index 0000000..561e9a9 Binary files /dev/null and b/data/images/autorace_aimleft.png differ diff --git a/data/images/autorace_aimright.png b/data/images/autorace_aimright.png new file mode 100644 index 0000000..836fe99 Binary files /dev/null and b/data/images/autorace_aimright.png differ diff --git a/data/images/autorace_gear1.png b/data/images/autorace_gear1.png new file mode 100644 index 0000000..b925ee2 Binary files /dev/null and b/data/images/autorace_gear1.png differ diff --git a/data/images/autorace_gear2.png b/data/images/autorace_gear2.png new file mode 100644 index 0000000..8a28ae8 Binary files /dev/null and b/data/images/autorace_gear2.png differ diff --git a/data/images/autorace_gear3.png b/data/images/autorace_gear3.png new file mode 100644 index 0000000..f97172e Binary files /dev/null and b/data/images/autorace_gear3.png differ diff --git a/data/images/autorace_gear4.png b/data/images/autorace_gear4.png new file mode 100644 index 0000000..b606cf5 Binary files /dev/null and b/data/images/autorace_gear4.png differ diff --git a/data/images/autorace_poweroff.png b/data/images/autorace_poweroff.png new file mode 100644 index 0000000..31429c5 Binary files /dev/null and b/data/images/autorace_poweroff.png differ diff --git a/data/images/autorace_poweron.png b/data/images/autorace_poweron.png new file mode 100644 index 0000000..b7ce3a7 Binary files /dev/null and b/data/images/autorace_poweron.png differ diff --git a/data/images/autorace_screen.png b/data/images/autorace_screen.png new file mode 100644 index 0000000..f3cd3e9 Binary files /dev/null and b/data/images/autorace_screen.png differ diff --git a/data/images/baseball_blip.png b/data/images/baseball_blip.png new file mode 100644 index 0000000..1ac3510 Binary files /dev/null and b/data/images/baseball_blip.png differ diff --git a/data/images/baseball_brightdigits.png b/data/images/baseball_brightdigits.png new file mode 100644 index 0000000..5d9e1db Binary files /dev/null and b/data/images/baseball_brightdigits.png differ diff --git a/data/images/baseball_dimdigits.png b/data/images/baseball_dimdigits.png new file mode 100644 index 0000000..290c073 Binary files /dev/null and b/data/images/baseball_dimdigits.png differ diff --git a/data/images/baseball_poweroff.png b/data/images/baseball_poweroff.png new file mode 100644 index 0000000..b6a6a79 Binary files /dev/null and b/data/images/baseball_poweroff.png differ diff --git a/data/images/baseball_pro1.png b/data/images/baseball_pro1.png new file mode 100644 index 0000000..8313a80 Binary files /dev/null and b/data/images/baseball_pro1.png differ diff --git a/data/images/baseball_pro2.png b/data/images/baseball_pro2.png new file mode 100644 index 0000000..6c6e7b6 Binary files /dev/null and b/data/images/baseball_pro2.png differ diff --git a/data/images/baseball_screen.png b/data/images/baseball_screen.png new file mode 100644 index 0000000..ff3cc45 Binary files /dev/null and b/data/images/baseball_screen.png differ diff --git a/data/images/basketball_screen.png b/data/images/basketball_screen.png new file mode 100644 index 0000000..75d9544 Binary files /dev/null and b/data/images/basketball_screen.png differ diff --git a/data/images/cover.png b/data/images/cover.png new file mode 100644 index 0000000..4c858e7 Binary files /dev/null and b/data/images/cover.png differ diff --git a/data/images/digits_f.png b/data/images/digits_f.png new file mode 100644 index 0000000..32da834 Binary files /dev/null and b/data/images/digits_f.png differ diff --git a/data/images/football2_poweroff.png b/data/images/football2_poweroff.png new file mode 100644 index 0000000..78c4455 Binary files /dev/null and b/data/images/football2_poweroff.png differ diff --git a/data/images/football2_pro1.png b/data/images/football2_pro1.png new file mode 100644 index 0000000..c3aed24 Binary files /dev/null and b/data/images/football2_pro1.png differ diff --git a/data/images/football2_pro2.png b/data/images/football2_pro2.png new file mode 100644 index 0000000..b199d2d Binary files /dev/null and b/data/images/football2_pro2.png differ diff --git a/data/images/football2_screen.png b/data/images/football2_screen.png new file mode 100644 index 0000000..4eef996 Binary files /dev/null and b/data/images/football2_screen.png differ diff --git a/data/images/football_poweroff.png b/data/images/football_poweroff.png new file mode 100644 index 0000000..9bd2ec8 Binary files /dev/null and b/data/images/football_poweroff.png differ diff --git a/data/images/football_pro1.png b/data/images/football_pro1.png new file mode 100644 index 0000000..d7a9335 Binary files /dev/null and b/data/images/football_pro1.png differ diff --git a/data/images/football_pro2.png b/data/images/football_pro2.png new file mode 100644 index 0000000..75947cf Binary files /dev/null and b/data/images/football_pro2.png differ diff --git a/data/images/football_screen.png b/data/images/football_screen.png new file mode 100644 index 0000000..4f8606f Binary files /dev/null and b/data/images/football_screen.png differ diff --git a/data/images/grrlib_logo.png b/data/images/grrlib_logo.png new file mode 100644 index 0000000..7a97548 Binary files /dev/null and b/data/images/grrlib_logo.png differ diff --git a/data/images/hockey_screen.png b/data/images/hockey_screen.png new file mode 100644 index 0000000..bf78ab5 Binary files /dev/null and b/data/images/hockey_screen.png differ diff --git a/data/images/hockeyca_screen.png b/data/images/hockeyca_screen.png new file mode 100644 index 0000000..ae20ca3 Binary files /dev/null and b/data/images/hockeyca_screen.png differ diff --git a/data/images/nodisp_screen.png b/data/images/nodisp_screen.png new file mode 100644 index 0000000..69e5009 Binary files /dev/null and b/data/images/nodisp_screen.png differ diff --git a/data/images/o_blip.png b/data/images/o_blip.png new file mode 100644 index 0000000..e36b551 Binary files /dev/null and b/data/images/o_blip.png differ diff --git a/data/images/poweroff_a.png b/data/images/poweroff_a.png new file mode 100644 index 0000000..3163d06 Binary files /dev/null and b/data/images/poweroff_a.png differ diff --git a/data/images/skislalom_aimcenter.png b/data/images/skislalom_aimcenter.png new file mode 100644 index 0000000..f39f19b Binary files /dev/null and b/data/images/skislalom_aimcenter.png differ diff --git a/data/images/skislalom_aimleft.png b/data/images/skislalom_aimleft.png new file mode 100644 index 0000000..ccb4fd3 Binary files /dev/null and b/data/images/skislalom_aimleft.png differ diff --git a/data/images/skislalom_aimright.png b/data/images/skislalom_aimright.png new file mode 100644 index 0000000..7c09444 Binary files /dev/null and b/data/images/skislalom_aimright.png differ diff --git a/data/images/skislalom_gear1.png b/data/images/skislalom_gear1.png new file mode 100644 index 0000000..6ab0464 Binary files /dev/null and b/data/images/skislalom_gear1.png differ diff --git a/data/images/skislalom_gear2.png b/data/images/skislalom_gear2.png new file mode 100644 index 0000000..72c4aa4 Binary files /dev/null and b/data/images/skislalom_gear2.png differ diff --git a/data/images/skislalom_gear3.png b/data/images/skislalom_gear3.png new file mode 100644 index 0000000..75a4eaa Binary files /dev/null and b/data/images/skislalom_gear3.png differ diff --git a/data/images/skislalom_gear4.png b/data/images/skislalom_gear4.png new file mode 100644 index 0000000..b606cf5 Binary files /dev/null and b/data/images/skislalom_gear4.png differ diff --git a/data/images/skislalom_gearknob.png b/data/images/skislalom_gearknob.png new file mode 100644 index 0000000..8da6bb9 Binary files /dev/null and b/data/images/skislalom_gearknob.png differ diff --git a/data/images/skislalom_powerknob.png b/data/images/skislalom_powerknob.png new file mode 100644 index 0000000..8da6bb9 Binary files /dev/null and b/data/images/skislalom_powerknob.png differ diff --git a/data/images/skislalom_poweroff.png b/data/images/skislalom_poweroff.png new file mode 100644 index 0000000..818c2ce Binary files /dev/null and b/data/images/skislalom_poweroff.png differ diff --git a/data/images/skislalom_poweron.png b/data/images/skislalom_poweron.png new file mode 100644 index 0000000..18c5944 Binary files /dev/null and b/data/images/skislalom_poweron.png differ diff --git a/data/images/skislalom_screen.png b/data/images/skislalom_screen.png new file mode 100644 index 0000000..c33a5e0 Binary files /dev/null and b/data/images/skislalom_screen.png differ diff --git a/data/images/soccer_screen.png b/data/images/soccer_screen.png new file mode 100644 index 0000000..f65411d Binary files /dev/null and b/data/images/soccer_screen.png differ diff --git a/data/images/spacealert_aimcenter.png b/data/images/spacealert_aimcenter.png new file mode 100644 index 0000000..28c374f Binary files /dev/null and b/data/images/spacealert_aimcenter.png differ diff --git a/data/images/spacealert_aimleft.png b/data/images/spacealert_aimleft.png new file mode 100644 index 0000000..3b75e16 Binary files /dev/null and b/data/images/spacealert_aimleft.png differ diff --git a/data/images/spacealert_aimright.png b/data/images/spacealert_aimright.png new file mode 100644 index 0000000..0db9a63 Binary files /dev/null and b/data/images/spacealert_aimright.png differ diff --git a/data/images/spacealert_poweroff.png b/data/images/spacealert_poweroff.png new file mode 100644 index 0000000..fde9685 Binary files /dev/null and b/data/images/spacealert_poweroff.png differ diff --git a/data/images/spacealert_poweron.png b/data/images/spacealert_poweron.png new file mode 100644 index 0000000..a85aa65 Binary files /dev/null and b/data/images/spacealert_poweron.png differ diff --git a/data/images/spacealert_screen.png b/data/images/spacealert_screen.png new file mode 100644 index 0000000..f2511c7 Binary files /dev/null and b/data/images/spacealert_screen.png differ diff --git a/data/images/subchase_blipbright.png b/data/images/subchase_blipbright.png new file mode 100644 index 0000000..c6c248d Binary files /dev/null and b/data/images/subchase_blipbright.png differ diff --git a/data/images/subchase_blipdim.png b/data/images/subchase_blipdim.png new file mode 100644 index 0000000..6cd3293 Binary files /dev/null and b/data/images/subchase_blipdim.png differ diff --git a/data/images/subchase_digits.png b/data/images/subchase_digits.png new file mode 100644 index 0000000..06282ae Binary files /dev/null and b/data/images/subchase_digits.png differ diff --git a/data/images/subchase_poweroff.png b/data/images/subchase_poweroff.png new file mode 100644 index 0000000..1ef2a0a Binary files /dev/null and b/data/images/subchase_poweroff.png differ diff --git a/data/images/subchase_poweron.png b/data/images/subchase_poweron.png new file mode 100644 index 0000000..c2b16ee Binary files /dev/null and b/data/images/subchase_poweron.png differ diff --git a/data/images/subchase_screen.png b/data/images/subchase_screen.png new file mode 100644 index 0000000..b67a964 Binary files /dev/null and b/data/images/subchase_screen.png differ diff --git a/data/images/v_blip.png b/data/images/v_blip.png new file mode 100644 index 0000000..d4a35e1 Binary files /dev/null and b/data/images/v_blip.png differ diff --git a/data/sounds/armorbattle_endgame.raw b/data/sounds/armorbattle_endgame.raw new file mode 100644 index 0000000..0f117ec Binary files /dev/null and b/data/sounds/armorbattle_endgame.raw differ diff --git a/data/sounds/armorbattle_enemy.raw b/data/sounds/armorbattle_enemy.raw new file mode 100644 index 0000000..5abda07 Binary files /dev/null and b/data/sounds/armorbattle_enemy.raw differ diff --git a/data/sounds/armorbattle_fire.raw b/data/sounds/armorbattle_fire.raw new file mode 100644 index 0000000..e8da87e Binary files /dev/null and b/data/sounds/armorbattle_fire.raw differ diff --git a/data/sounds/armorbattle_hit.raw b/data/sounds/armorbattle_hit.raw new file mode 100644 index 0000000..3060e26 Binary files /dev/null and b/data/sounds/armorbattle_hit.raw differ diff --git a/data/sounds/armorbattle_near.raw b/data/sounds/armorbattle_near.raw new file mode 100644 index 0000000..2324c56 Binary files /dev/null and b/data/sounds/armorbattle_near.raw differ diff --git a/data/sounds/armorbattle_score.raw b/data/sounds/armorbattle_score.raw new file mode 100644 index 0000000..d3552e3 Binary files /dev/null and b/data/sounds/armorbattle_score.raw differ diff --git a/data/sounds/armorbattle_tick.raw b/data/sounds/armorbattle_tick.raw new file mode 100644 index 0000000..6870717 Binary files /dev/null and b/data/sounds/armorbattle_tick.raw differ diff --git a/data/sounds/autorace_gear1.raw b/data/sounds/autorace_gear1.raw new file mode 100644 index 0000000..99dd3f3 Binary files /dev/null and b/data/sounds/autorace_gear1.raw differ diff --git a/data/sounds/autorace_gear2.raw b/data/sounds/autorace_gear2.raw new file mode 100644 index 0000000..817ff55 Binary files /dev/null and b/data/sounds/autorace_gear2.raw differ diff --git a/data/sounds/autorace_gear3.raw b/data/sounds/autorace_gear3.raw new file mode 100644 index 0000000..a07e3b0 Binary files /dev/null and b/data/sounds/autorace_gear3.raw differ diff --git a/data/sounds/autorace_gear4.raw b/data/sounds/autorace_gear4.raw new file mode 100644 index 0000000..96235e6 Binary files /dev/null and b/data/sounds/autorace_gear4.raw differ diff --git a/data/sounds/autorace_hit.raw b/data/sounds/autorace_hit.raw new file mode 100644 index 0000000..35055ee Binary files /dev/null and b/data/sounds/autorace_hit.raw differ diff --git a/data/sounds/autorace_time.raw b/data/sounds/autorace_time.raw new file mode 100644 index 0000000..1b23993 Binary files /dev/null and b/data/sounds/autorace_time.raw differ diff --git a/data/sounds/autorace_win.raw b/data/sounds/autorace_win.raw new file mode 100644 index 0000000..771ba2d Binary files /dev/null and b/data/sounds/autorace_win.raw differ diff --git a/data/sounds/baseball_endgame.raw b/data/sounds/baseball_endgame.raw new file mode 100644 index 0000000..24e0adb Binary files /dev/null and b/data/sounds/baseball_endgame.raw differ diff --git a/data/sounds/baseball_endpossession.raw b/data/sounds/baseball_endpossession.raw new file mode 100644 index 0000000..c5d9bc8 Binary files /dev/null and b/data/sounds/baseball_endpossession.raw differ diff --git a/data/sounds/baseball_hit.raw b/data/sounds/baseball_hit.raw new file mode 100644 index 0000000..91ef8a4 Binary files /dev/null and b/data/sounds/baseball_hit.raw differ diff --git a/data/sounds/baseball_out.raw b/data/sounds/baseball_out.raw new file mode 100644 index 0000000..e3f714d Binary files /dev/null and b/data/sounds/baseball_out.raw differ diff --git a/data/sounds/baseball_run.raw b/data/sounds/baseball_run.raw new file mode 100644 index 0000000..5678c6a Binary files /dev/null and b/data/sounds/baseball_run.raw differ diff --git a/data/sounds/baseball_strike.raw b/data/sounds/baseball_strike.raw new file mode 100644 index 0000000..edf911f Binary files /dev/null and b/data/sounds/baseball_strike.raw differ diff --git a/data/sounds/basketball_bounce.raw b/data/sounds/basketball_bounce.raw new file mode 100644 index 0000000..ffe4457 Binary files /dev/null and b/data/sounds/basketball_bounce.raw differ diff --git a/data/sounds/basketball_endgame.raw b/data/sounds/basketball_endgame.raw new file mode 100644 index 0000000..aea5dff Binary files /dev/null and b/data/sounds/basketball_endgame.raw differ diff --git a/data/sounds/basketball_endplay.raw b/data/sounds/basketball_endplay.raw new file mode 100644 index 0000000..9ed3def Binary files /dev/null and b/data/sounds/basketball_endplay.raw differ diff --git a/data/sounds/basketball_endquarter.raw b/data/sounds/basketball_endquarter.raw new file mode 100644 index 0000000..b675f9e Binary files /dev/null and b/data/sounds/basketball_endquarter.raw differ diff --git a/data/sounds/basketball_score.raw b/data/sounds/basketball_score.raw new file mode 100644 index 0000000..80ba074 Binary files /dev/null and b/data/sounds/basketball_score.raw differ diff --git a/data/sounds/basketball_tick.raw b/data/sounds/basketball_tick.raw new file mode 100644 index 0000000..0aab4d8 Binary files /dev/null and b/data/sounds/basketball_tick.raw differ diff --git a/data/sounds/football2_charge.raw b/data/sounds/football2_charge.raw new file mode 100644 index 0000000..fb23b1d Binary files /dev/null and b/data/sounds/football2_charge.raw differ diff --git a/data/sounds/football2_chargestart.raw b/data/sounds/football2_chargestart.raw new file mode 100644 index 0000000..db15d01 Binary files /dev/null and b/data/sounds/football2_chargestart.raw differ diff --git a/data/sounds/football2_endplay.raw b/data/sounds/football2_endplay.raw new file mode 100644 index 0000000..21ca95d Binary files /dev/null and b/data/sounds/football2_endplay.raw differ diff --git a/data/sounds/football2_endpossession.raw b/data/sounds/football2_endpossession.raw new file mode 100644 index 0000000..311173d Binary files /dev/null and b/data/sounds/football2_endpossession.raw differ diff --git a/data/sounds/football2_endquarter.raw b/data/sounds/football2_endquarter.raw new file mode 100644 index 0000000..11829a1 Binary files /dev/null and b/data/sounds/football2_endquarter.raw differ diff --git a/data/sounds/football2_firstdown.raw b/data/sounds/football2_firstdown.raw new file mode 100644 index 0000000..c7df413 Binary files /dev/null and b/data/sounds/football2_firstdown.raw differ diff --git a/data/sounds/football2_runback.raw b/data/sounds/football2_runback.raw new file mode 100644 index 0000000..e02a5b6 Binary files /dev/null and b/data/sounds/football2_runback.raw differ diff --git a/data/sounds/football2_safety.raw b/data/sounds/football2_safety.raw new file mode 100644 index 0000000..083181e Binary files /dev/null and b/data/sounds/football2_safety.raw differ diff --git a/data/sounds/football2_tick.raw b/data/sounds/football2_tick.raw new file mode 100644 index 0000000..d8c4c03 Binary files /dev/null and b/data/sounds/football2_tick.raw differ diff --git a/data/sounds/football2_touchdown.raw b/data/sounds/football2_touchdown.raw new file mode 100644 index 0000000..5b93432 Binary files /dev/null and b/data/sounds/football2_touchdown.raw differ diff --git a/data/sounds/football_endplay.raw b/data/sounds/football_endplay.raw new file mode 100644 index 0000000..d37d344 Binary files /dev/null and b/data/sounds/football_endplay.raw differ diff --git a/data/sounds/football_endpossession.raw b/data/sounds/football_endpossession.raw new file mode 100644 index 0000000..6d04e2a Binary files /dev/null and b/data/sounds/football_endpossession.raw differ diff --git a/data/sounds/football_score.raw b/data/sounds/football_score.raw new file mode 100644 index 0000000..f02a1bf Binary files /dev/null and b/data/sounds/football_score.raw differ diff --git a/data/sounds/football_tick.raw b/data/sounds/football_tick.raw new file mode 100644 index 0000000..8c0541c Binary files /dev/null and b/data/sounds/football_tick.raw differ diff --git a/data/sounds/hockey_bump.raw b/data/sounds/hockey_bump.raw new file mode 100644 index 0000000..8fecddc Binary files /dev/null and b/data/sounds/hockey_bump.raw differ diff --git a/data/sounds/hockey_deflect.raw b/data/sounds/hockey_deflect.raw new file mode 100644 index 0000000..1a5c7c2 Binary files /dev/null and b/data/sounds/hockey_deflect.raw differ diff --git a/data/sounds/hockey_endgame.raw b/data/sounds/hockey_endgame.raw new file mode 100644 index 0000000..3c55ada Binary files /dev/null and b/data/sounds/hockey_endgame.raw differ diff --git a/data/sounds/hockey_endperiod.raw b/data/sounds/hockey_endperiod.raw new file mode 100644 index 0000000..7fe96a1 Binary files /dev/null and b/data/sounds/hockey_endperiod.raw differ diff --git a/data/sounds/hockey_penalty.raw b/data/sounds/hockey_penalty.raw new file mode 100644 index 0000000..49ad028 Binary files /dev/null and b/data/sounds/hockey_penalty.raw differ diff --git a/data/sounds/hockey_poke.raw b/data/sounds/hockey_poke.raw new file mode 100644 index 0000000..252f10b Binary files /dev/null and b/data/sounds/hockey_poke.raw differ diff --git a/data/sounds/hockey_score.raw b/data/sounds/hockey_score.raw new file mode 100644 index 0000000..dd39e7c Binary files /dev/null and b/data/sounds/hockey_score.raw differ diff --git a/data/sounds/hockey_steal.raw b/data/sounds/hockey_steal.raw new file mode 100644 index 0000000..3475674 Binary files /dev/null and b/data/sounds/hockey_steal.raw differ diff --git a/data/sounds/hockey_tick.raw b/data/sounds/hockey_tick.raw new file mode 100644 index 0000000..b138b91 Binary files /dev/null and b/data/sounds/hockey_tick.raw differ diff --git a/data/sounds/hockeyca_bounce.raw b/data/sounds/hockeyca_bounce.raw new file mode 100644 index 0000000..2159d83 Binary files /dev/null and b/data/sounds/hockeyca_bounce.raw differ diff --git a/data/sounds/hockeyca_endgame.raw b/data/sounds/hockeyca_endgame.raw new file mode 100644 index 0000000..45c1edd Binary files /dev/null and b/data/sounds/hockeyca_endgame.raw differ diff --git a/data/sounds/hockeyca_endperiod.raw b/data/sounds/hockeyca_endperiod.raw new file mode 100644 index 0000000..33806d0 Binary files /dev/null and b/data/sounds/hockeyca_endperiod.raw differ diff --git a/data/sounds/hockeyca_endplay.raw b/data/sounds/hockeyca_endplay.raw new file mode 100644 index 0000000..825c3aa Binary files /dev/null and b/data/sounds/hockeyca_endplay.raw differ diff --git a/data/sounds/hockeyca_score.raw b/data/sounds/hockeyca_score.raw new file mode 100644 index 0000000..bff659b Binary files /dev/null and b/data/sounds/hockeyca_score.raw differ diff --git a/data/sounds/hockeyca_tick.raw b/data/sounds/hockeyca_tick.raw new file mode 100644 index 0000000..b0e5dd6 Binary files /dev/null and b/data/sounds/hockeyca_tick.raw differ diff --git a/data/sounds/skislalom_gear1.raw b/data/sounds/skislalom_gear1.raw new file mode 100644 index 0000000..99dd3f3 Binary files /dev/null and b/data/sounds/skislalom_gear1.raw differ diff --git a/data/sounds/skislalom_gear2.raw b/data/sounds/skislalom_gear2.raw new file mode 100644 index 0000000..817ff55 Binary files /dev/null and b/data/sounds/skislalom_gear2.raw differ diff --git a/data/sounds/skislalom_gear3.raw b/data/sounds/skislalom_gear3.raw new file mode 100644 index 0000000..a07e3b0 Binary files /dev/null and b/data/sounds/skislalom_gear3.raw differ diff --git a/data/sounds/skislalom_gear4.raw b/data/sounds/skislalom_gear4.raw new file mode 100644 index 0000000..96235e6 Binary files /dev/null and b/data/sounds/skislalom_gear4.raw differ diff --git a/data/sounds/skislalom_hit.raw b/data/sounds/skislalom_hit.raw new file mode 100644 index 0000000..35055ee Binary files /dev/null and b/data/sounds/skislalom_hit.raw differ diff --git a/data/sounds/skislalom_time.raw b/data/sounds/skislalom_time.raw new file mode 100644 index 0000000..1b23993 Binary files /dev/null and b/data/sounds/skislalom_time.raw differ diff --git a/data/sounds/skislalom_win.raw b/data/sounds/skislalom_win.raw new file mode 100644 index 0000000..771ba2d Binary files /dev/null and b/data/sounds/skislalom_win.raw differ diff --git a/data/sounds/soccer_bounce.raw b/data/sounds/soccer_bounce.raw new file mode 100644 index 0000000..4cf80b0 Binary files /dev/null and b/data/sounds/soccer_bounce.raw differ diff --git a/data/sounds/soccer_endgame.raw b/data/sounds/soccer_endgame.raw new file mode 100644 index 0000000..d7ca3e5 Binary files /dev/null and b/data/sounds/soccer_endgame.raw differ diff --git a/data/sounds/soccer_endperiod.raw b/data/sounds/soccer_endperiod.raw new file mode 100644 index 0000000..7387dd2 Binary files /dev/null and b/data/sounds/soccer_endperiod.raw differ diff --git a/data/sounds/soccer_endplay.raw b/data/sounds/soccer_endplay.raw new file mode 100644 index 0000000..edd9195 Binary files /dev/null and b/data/sounds/soccer_endplay.raw differ diff --git a/data/sounds/soccer_score.raw b/data/sounds/soccer_score.raw new file mode 100644 index 0000000..edeba02 Binary files /dev/null and b/data/sounds/soccer_score.raw differ diff --git a/data/sounds/soccer_tick.raw b/data/sounds/soccer_tick.raw new file mode 100644 index 0000000..6717800 Binary files /dev/null and b/data/sounds/soccer_tick.raw differ diff --git a/data/sounds/spacealert_fire.raw b/data/sounds/spacealert_fire.raw new file mode 100644 index 0000000..9872b6f Binary files /dev/null and b/data/sounds/spacealert_fire.raw differ diff --git a/data/sounds/spacealert_hit.raw b/data/sounds/spacealert_hit.raw new file mode 100644 index 0000000..6f78a26 Binary files /dev/null and b/data/sounds/spacealert_hit.raw differ diff --git a/data/sounds/spacealert_lose.raw b/data/sounds/spacealert_lose.raw new file mode 100644 index 0000000..05be7c5 Binary files /dev/null and b/data/sounds/spacealert_lose.raw differ diff --git a/data/sounds/spacealert_raider.raw b/data/sounds/spacealert_raider.raw new file mode 100644 index 0000000..0712cac Binary files /dev/null and b/data/sounds/spacealert_raider.raw differ diff --git a/data/sounds/spacealert_win.raw b/data/sounds/spacealert_win.raw new file mode 100644 index 0000000..f644e56 Binary files /dev/null and b/data/sounds/spacealert_win.raw differ diff --git a/data/sounds/subchase_charge.raw b/data/sounds/subchase_charge.raw new file mode 100644 index 0000000..d537f7a Binary files /dev/null and b/data/sounds/subchase_charge.raw differ diff --git a/data/sounds/subchase_hit.raw b/data/sounds/subchase_hit.raw new file mode 100644 index 0000000..a74c4c7 Binary files /dev/null and b/data/sounds/subchase_hit.raw differ diff --git a/data/sounds/subchase_sink.raw b/data/sounds/subchase_sink.raw new file mode 100644 index 0000000..f27951b Binary files /dev/null and b/data/sounds/subchase_sink.raw differ diff --git a/data/sounds/subchase_sonar.raw b/data/sounds/subchase_sonar.raw new file mode 100644 index 0000000..ff58996 Binary files /dev/null and b/data/sounds/subchase_sonar.raw differ diff --git a/data/wiimote/WK1.png b/data/wiimote/WK1.png new file mode 100644 index 0000000..18ace13 Binary files /dev/null and b/data/wiimote/WK1.png differ diff --git a/data/wiimote/WK2.png b/data/wiimote/WK2.png new file mode 100644 index 0000000..b18b4f0 Binary files /dev/null and b/data/wiimote/WK2.png differ diff --git a/data/wiimote/WKA.png b/data/wiimote/WKA.png new file mode 100644 index 0000000..38279f6 Binary files /dev/null and b/data/wiimote/WKA.png differ diff --git a/data/wiimote/WKB.png b/data/wiimote/WKB.png new file mode 100644 index 0000000..3575ac8 Binary files /dev/null and b/data/wiimote/WKB.png differ diff --git a/data/wiimote/WKBLR.png b/data/wiimote/WKBLR.png new file mode 100644 index 0000000..b3987ef Binary files /dev/null and b/data/wiimote/WKBLR.png differ diff --git a/data/wiimote/WKBUD.png b/data/wiimote/WKBUD.png new file mode 100644 index 0000000..e5808f3 Binary files /dev/null and b/data/wiimote/WKBUD.png differ diff --git a/data/wiimote/WKDPAD.png b/data/wiimote/WKDPAD.png new file mode 100644 index 0000000..c9c5bba Binary files /dev/null and b/data/wiimote/WKDPAD.png differ diff --git a/data/wiimote/WKHOME.png b/data/wiimote/WKHOME.png new file mode 100644 index 0000000..798c2c1 Binary files /dev/null and b/data/wiimote/WKHOME.png differ diff --git a/data/wiimote/WKLD.png b/data/wiimote/WKLD.png new file mode 100644 index 0000000..d186e09 Binary files /dev/null and b/data/wiimote/WKLD.png differ diff --git a/data/wiimote/WKLR.png b/data/wiimote/WKLR.png new file mode 100644 index 0000000..a667061 Binary files /dev/null and b/data/wiimote/WKLR.png differ diff --git a/data/wiimote/WKLU.png b/data/wiimote/WKLU.png new file mode 100644 index 0000000..9514f26 Binary files /dev/null and b/data/wiimote/WKLU.png differ diff --git a/data/wiimote/WKMINUS.png b/data/wiimote/WKMINUS.png new file mode 100644 index 0000000..9f619cc Binary files /dev/null and b/data/wiimote/WKMINUS.png differ diff --git a/data/wiimote/WKPLUS.png b/data/wiimote/WKPLUS.png new file mode 100644 index 0000000..99fec8b Binary files /dev/null and b/data/wiimote/WKPLUS.png differ diff --git a/data/wiimote/WKRD.png b/data/wiimote/WKRD.png new file mode 100644 index 0000000..846ab5f Binary files /dev/null and b/data/wiimote/WKRD.png differ diff --git a/data/wiimote/WKRU.png b/data/wiimote/WKRU.png new file mode 100644 index 0000000..aad6080 Binary files /dev/null and b/data/wiimote/WKRU.png differ diff --git a/data/wiimote/WKUD.png b/data/wiimote/WKUD.png new file mode 100644 index 0000000..11381d6 Binary files /dev/null and b/data/wiimote/WKUD.png differ diff --git a/source/Games.c b/source/Games.c new file mode 100644 index 0000000..b8f0b2f --- /dev/null +++ b/source/Games.c @@ -0,0 +1,334 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "LED_Handled.h" +#include "games.h" + +#include "autorace.h" +#include "spacealert.h" +#include "basketball.h" +#include "football.h" +#include "football2.h" +#include "hockey.h" +#include "hockeyca.h" +#include "soccer.h" +#include "armorbattle.h" +#include "baseball.h" +#include "subchase.h" +#include "armorbattle_screen_png.h" +#include "autorace_screen_png.h" +#include "baseball_screen_png.h" +#include "basketball_screen_png.h" +#include "football_screen_png.h" +#include "football2_screen_png.h" +#include "hockey_screen_png.h" +#include "hockeyca_screen_png.h" +#include "skislalom_screen_png.h" +#include "soccer_screen_png.h" +#include "spacealert_screen_png.h" +#include "subchase_screen_png.h" +#include "nodisp_screen_png.h" + +GAMECONTEXT gGameContext[NUM_GAMES] = +{ + // armor battle + { + GAME_ARMORBATTLE, + 150, + "Armor Battle", + "armorbattle", + ArmorBattle_Init, + ArmorBattle_DeInit, + ArmorBattle_Run, + ArmorBattle_SetSkill, + ArmorBattle_GetSkill, + ArmorBattle_PowerOn, + ArmorBattle_PowerOff, + ArmorBattle_GetPower, + ArmorBattle_Paint, + ArmorBattle_GetSize, + armorbattle_screen_png, + ArmorBattle_Help, + }, + // auto race + { + GAME_AUTORACE, + 100,//65 + "Auto Race", + "autorace", + AutoRace_Init, + AutoRace_DeInit, + AutoRace_Run, + AutoRace_SetSkill, + AutoRace_GetSkill, + AutoRace_PowerOn, + AutoRace_PowerOff, + AutoRace_GetPower, + AutoRace_Paint, + AutoRace_GetSize, + autorace_screen_png, + AutoRace_Help + }, + // baseball + { + GAME_BASEBALL, + 10, + "Baseball", + "baseball", + Baseball_Init, + Baseball_DeInit, + Baseball_Run, + Baseball_SetSkill, + Baseball_GetSkill, + Baseball_PowerOn, + Baseball_PowerOff, + Baseball_GetPower, + Baseball_Paint, + Baseball_GetSize, + baseball_screen_png, + Baseball_Help + }, + // basketball + { + GAME_BASKETBALL, + 60, + "Basketball", + "basketball", + Basketball_Init, + Basketball_DeInit, + Basketball_Run, + Basketball_SetSkill, + Basketball_GetSkill, + Basketball_PowerOn, + Basketball_PowerOff, + Basketball_GetPower, + Basketball_Paint, + Basketball_GetSize, + basketball_screen_png, + Basketball_Help + }, + // basketball 2 + { + GAME_BASKETBALL2, + 0, + "Basketball II", + "basketball2", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nodisp_screen_png, + NULL + }, + // football + { + GAME_FOOTBALL, + 55, + "Football", + "football", + Football_Init, + Football_DeInit, + Football_Run, + Football_SetSkill, + Football_GetSkill, + Football_PowerOn, + Football_PowerOff, + Football_GetPower, + Football_Paint, + Football_GetSize, + football_screen_png, + Football_Help, + }, + // football 2 + { + GAME_FOOTBALL2, + 50, + "Football II", + "football2", + Football2_Init, + Football2_DeInit, + Football2_Run, + Football2_SetSkill, + Football2_GetSkill, + Football2_PowerOn, + Football2_PowerOff, + Football2_GetPower, + Football2_Paint, + Football2_GetSize, + football2_screen_png, + Football2_Help, + }, + // hockey + { + GAME_HOCKEY, + 60, + "Hockey", + "hockey", + Hockey_Init, + Hockey_DeInit, + Hockey_Run, + Hockey_SetSkill, + Hockey_GetSkill, + Hockey_PowerOn, + Hockey_PowerOff, + Hockey_GetPower, + Hockey_Paint, + Hockey_GetSize, + hockey_screen_png, + Hockey_Help + }, + // hockey (canadian) + { + GAME_HOCKEYCA, + 60, + "Hockey (Canadian)", + "hockeyca", + HockeyCa_Init, + HockeyCa_DeInit, + HockeyCa_Run, + HockeyCa_SetSkill, + HockeyCa_GetSkill, + HockeyCa_PowerOn, + HockeyCa_PowerOff, + HockeyCa_GetPower, + HockeyCa_Paint, + HockeyCa_GetSize, + hockeyca_screen_png, + HockeyCa_Help + }, + // ski slalom + { + GAME_SKISLALOM, + 65, + "Ski Slalom", + "skislalom", + SkiSlalom_Init, + AutoRace_DeInit, + AutoRace_Run, + AutoRace_SetSkill, + AutoRace_GetSkill, + AutoRace_PowerOn, + AutoRace_PowerOff, + AutoRace_GetPower, + AutoRace_Paint, + AutoRace_GetSize, + skislalom_screen_png, + SkiSlalom_Help + }, + // soccer + { + GAME_SOCCER, + 60, + "Soccer", + "soccer", + Soccer_Init, + Soccer_DeInit, + Soccer_Run, + Soccer_SetSkill, + Soccer_GetSkill, + Soccer_PowerOn, + Soccer_PowerOff, + Soccer_GetPower, + Soccer_Paint, + Soccer_GetSize, + soccer_screen_png, + Soccer_Help + }, + // soccer 2 + { + GAME_SOCCER2, + 0, + "Soccer II", + "soccer2", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nodisp_screen_png, + NULL + }, + // space alert + { + GAME_SPACEALERT, + 110, + "Space Alert", + "spacealert", + SpaceAlert_Init, + SpaceAlert_DeInit, + SpaceAlert_Run, + NULL, + NULL, + SpaceAlert_PowerOn, + SpaceAlert_PowerOff, + SpaceAlert_GetPower, + SpaceAlert_Paint, + SpaceAlert_GetSize, + spacealert_screen_png, + SpaceAlert_Help + }, + // subchase + { + GAME_SUBCHASE, + 60, + "Sub Chase", + "subchase", + SubChase_Init, + SubChase_DeInit, + SubChase_Run, + NULL, + NULL, + SubChase_PowerOn, + SubChase_PowerOff, + SubChase_GetPower, + SubChase_Paint, + SubChase_GetSize, + subchase_screen_png, + SubChase_Help + } +}; + +GAMECONTEXT *gCurrentGame = NULL; diff --git a/source/Games.h b/source/Games.h new file mode 100644 index 0000000..0d3aed3 --- /dev/null +++ b/source/Games.h @@ -0,0 +1,87 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __GAMES_H__ +#define __GAMES_H__ + +// game ids +#define GAME_ARMORBATTLE 0 +#define GAME_AUTORACE 1 +#define GAME_BASEBALL 2 +#define GAME_BASKETBALL 3 +#define GAME_BASKETBALL2 4 +#define GAME_FOOTBALL 5 +#define GAME_FOOTBALL2 6 +#define GAME_HOCKEY 7 +#define GAME_HOCKEYCA 8 +#define GAME_SKISLALOM 9 +#define GAME_SOCCER 10 +#define GAME_SOCCER2 11 +#define GAME_SPACEALERT 12 +#define GAME_SUBCHASE 13 + +#define NUM_GAMES 14 + +typedef struct GAMECONTEXT +{ + int id; + + // is the interval in milliseconds that the game's + // 'run' function should be called + int tu; + + char *szName; + char *szDir; + + void (*Init)(void); + void (*DeInit)(void); + void (*Run)(int tu); + void (*SetSkill)(int i); + int (*GetSkill)(void); + void (*PowerOn)(void); + void (*PowerOff)(void); + int (*GetPower)(void); + void (*Paint)(void); + void (*GetSize)(int *w, int *h); + const u8 *screen; + void (*Help)(void); +}GAMECONTEXT; + +extern GAMECONTEXT gGameContext[NUM_GAMES]; +extern GAMECONTEXT *gCurrentGame; + + +#endif diff --git a/source/LED_Handled.h b/source/LED_Handled.h new file mode 100644 index 0000000..dc372e3 --- /dev/null +++ b/source/LED_Handled.h @@ -0,0 +1,64 @@ +/* + * LEDhead for Wii + * Copyright (C) 2017-2020 Nebiun + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _LED_Handled_h_ +#define _LED_Handled_h_ +#include +#include +#include +#include +#include +#include + +#define VAL_ROUNDING(v,d) (((v) + (d) - 1)/(d)) + +#define IR_X_CORRECTION 64 +#define IR_Y_CORRECTION 20 + +#define realx(x) ((x) + (rmode->viWidth - 240)/2) +#define realy(y) ((y) + 20) + +// draw_poweroff_a modes +#define POWER_POS_OFF 0 +#define POWER_POS_MODE1 1 +#define POWER_POS_MODE2 2 + +// draw_vblip/draw_oblip modes +#define BLIP_TYPE_NORMAL 0 +#define BLIP_TYPE_BRIGHT 1 +#define BLIP_TYPE_FLICKER 2 + +// draw_digit_f modes +#define DIGIT_TYPE_NORMAL 0 +#define DIGIT_TYPE_FLOAT 1 +#define DIGIT_TYPE_SPECIAL 2 + +extern int trace; +extern void print_text(int x, int y, u32 rgba, const char *fmt, ...); + +extern int draw_digit(int x, int y, int val); +extern int print_digit(int x, int y, int pass, int val, int max); +extern int draw_digit_f(int x, int y, int val, int flag); + +extern int draw_poweroff_a(int x, int y, int val); +extern int draw_vblip(int x, int y, int type); +extern int draw_oblip(int x, int y, int type); + +extern void debugPrintf(int x, int y, u32 rgba, const char *fmt, ...); +extern void debugDestroy(void); +#endif \ No newline at end of file diff --git a/source/blip.c b/source/blip.c new file mode 100644 index 0000000..31b2e47 --- /dev/null +++ b/source/blip.c @@ -0,0 +1,75 @@ +/* + * LEDhead for Wii + * Copyright (C) 2017-2020 Nebiun + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "LED_Handled.h" +#include "v_blip_png.h" +#include "o_blip_png.h" + +#define V_BLIP_H 4 +#define V_BLIP_W 4 +#define O_BLIP_H 4 +#define O_BLIP_W 4 + +static inline int _drawBlip(int x, int y, int type, GRRLIB_texImg *blip) +{ + int idx; + + switch(type) { + case BLIP_TYPE_BRIGHT: + idx = 1; + break; + case BLIP_TYPE_FLICKER: + idx = 2; + break; + case BLIP_TYPE_NORMAL: + default: + idx = 0; + break; + } + GRRLIB_DrawTile(realx(x), realy(y), blip, 0, 1, 1, 0xFFFFFFFF, idx); + + return idx; +} + +int draw_vblip(int x, int y, int type) +{ + static GRRLIB_texImg *blip = NULL; + + if(blip == NULL) { + blip = GRRLIB_LoadTexture(v_blip_png); + if(blip == NULL) + return -1; + GRRLIB_InitTileSet(blip, V_BLIP_W, V_BLIP_H, 0); + } + + return _drawBlip(x, y, type, blip); +} + +int draw_oblip(int x, int y, int type) +{ + static GRRLIB_texImg *blip = NULL; + + if(blip == NULL) { + blip = GRRLIB_LoadTexture(o_blip_png); + if(blip == NULL) + return -1; + GRRLIB_InitTileSet(blip, O_BLIP_W, O_BLIP_H, 0); + } + + return _drawBlip(x, y, type, blip); +} diff --git a/source/digit.c b/source/digit.c new file mode 100644 index 0000000..d46dfe8 --- /dev/null +++ b/source/digit.c @@ -0,0 +1,88 @@ +/* + * LEDhead for Wii + * Copyright (C) 2017-2020 Nebiun + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "LED_Handled.h" +#include "digits_f_png.h" + +#define DIGIT_W 8 +#define DIGIT_H 12 + +int draw_digit_f(int x, int y, int val, int flag) +{ + static GRRLIB_texImg *digit = NULL; + int idx = -1; + + if(digit == NULL) { + digit = GRRLIB_LoadTexture(digits_f_png); + if(digit == NULL) + return -1; + GRRLIB_InitTileSet(digit, DIGIT_W, DIGIT_H, 0); + } + + switch(flag) { + case DIGIT_TYPE_NORMAL: + if(val == -1) + idx = 0; + else + idx = 1 + val%10; + break; + case DIGIT_TYPE_FLOAT: + if(val == -1) + idx = 11; + else + idx = 12 + val%10; + break; + case DIGIT_TYPE_SPECIAL: + idx = 23 + val%2; + break; + } + if(idx < 0) + return -1; + + GRRLIB_DrawTile(realx(x), realy(y), digit, 0, 1, 1, 0xFFFFFFFF, idx); + return 0; +} + +int draw_digit(int x, int y, int val) +{ + return draw_digit_f(x, y, val, DIGIT_TYPE_NORMAL); +} + +int print_digit(int x, int y, int pass, int val, int max) +{ + char n[16]; + register int i; + register int pos = 0; + + if(max >= sizeof(n)) + return -1; + if(val == -1) { + for(i=0; i. + */ + +#include "LED_Handled.h" +#include "FreeSerif_ttf.h" +#include "xped_ttf.h" + +static GRRLIB_ttfFont *gameFont = NULL; +static GRRLIB_ttfFont *debugFont = NULL; + +void print_text(int x, int y, u32 rgba, const char *fmt, ...) +{ + char lbuf[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(lbuf,sizeof(lbuf)-1,fmt,args); + va_end(args); + lbuf[sizeof(lbuf)-1] = '\0'; /* tappo */ + + if(gameFont == NULL) { + gameFont = GRRLIB_LoadTTF(xped_ttf, xped_ttf_size); + if(gameFont == NULL) { + return; + } + } + GRRLIB_PrintfTTF(x, y, gameFont, lbuf, 20, rgba); +} + +void debugDestroy(void) +{ + if(debugFont != NULL) + GRRLIB_FreeTTF(debugFont); +} + +void debugPrintf(int x, int y, u32 rgba, const char *fmt, ...) +{ + char lbuf[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(lbuf,sizeof(lbuf)-1,fmt,args); + va_end(args); + lbuf[sizeof(lbuf)-1] = '\0'; /* tappo */ + + if(debugFont == NULL) { + debugFont = GRRLIB_LoadTTF(FreeSerif_ttf, FreeSerif_ttf_size); + if(debugFont == NULL) { + return; + } + } + GRRLIB_PrintfTTF(x, y, debugFont, lbuf, 20, rgba); +} diff --git a/source/game/ArmorBattle.c b/source/game/ArmorBattle.c new file mode 100644 index 0000000..59dbc3f --- /dev/null +++ b/source/game/ArmorBattle.c @@ -0,0 +1,641 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#include "ArmorBattle.h" +#include "Games.h" + + +// constants + +typedef int BLIP; + +static BLIP Blips[ARMORBATTLE_BLIP_COLUMNS][ARMORBATTLE_BLIP_ROWS]; + + +// game variables +static BOOL bGameOver; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bGameStarted; + +static int nGameTimer; +static int nScore; +static int nHits; +static int nDamageCount; + +static int nPlayerStartX; +static int nPlayerStartY; + +static void PaintGame(int nDisplay); +static void InitGame(); +static void PositionPlayers(); +static void PlantMines(); + +typedef struct OBJECT +{ + int x; + int y; +}OBJECT; + +static OBJECT player; +static OBJECT enemy; +static OBJECT mines[4]; + +BOOL ArmorBattle_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void ArmorBattle_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void ArmorBattle_PowerOff() +{ + bPower = FALSE; +} + +int ArmorBattle_GetSkill() +{ + return 0; +} + +void ArmorBattle_SetSkill(int i) +{ +} + +void InitGame() +{ + bGameOver = FALSE; + nGameTimer = 0; + bGameStarted = FALSE; + nGameTimer = 0; + nScore = 0; + nHits = 0; + nDamageCount = 0; + + nPlayerStartX = 4; + nPlayerStartY = 3; + + player.x = nPlayerStartX; + player.y = nPlayerStartY; + + enemy.x = 1; + enemy.y = 1; + + PlantMines(); + + Platform_IsNewSecond(); +} + + +void ArmorBattle_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < ARMORBATTLE_BLIP_ROWS; y++){ + for (x = 0; x < ARMORBATTLE_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + // update the game timer + if (Platform_IsNewSecond()) + { + if (!bGameOver && bPower && bGameStarted) + { + ++nGameTimer; + if (nGameTimer > 99) + { + // time's up -- game over! + bGameOver = TRUE; + + ArmorBattle_StopMineSound(); + ArmorBattle_ClearScreen(); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + + // put the tanks in their starting positions + player.x = nPlayerStartX; + player.y = nPlayerStartY; + } + else + { + // check to see if player tank is in range for enemy tank to fire + if ( ((player.x-1 == enemy.x) && (player.y == enemy.y)) + || ((player.x+1 == enemy.x) && (player.y == enemy.y)) + + || ((player.x == enemy.x) && (player.y-1 == enemy.y)) + || ((player.x == enemy.x) && (player.y+1 == enemy.y)) + + || ((player.x-1 == enemy.x) && (player.y-1 == enemy.y)) + || ((player.x+1 == enemy.x) && (player.y+1 == enemy.y)) + + || ((player.x-1 == enemy.x) && (player.y+1 == enemy.y)) + || ((player.x+1 == enemy.x) && (player.y-1 == enemy.y))) + { + // in range + if (nDamageCount > 0) + { + ArmorBattle_ClearScreen(); + ArmorBattle_StopMineSound(); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_ENEMY, PLAYSOUNDFLAGS_PRIORITY); + } + ++nDamageCount; + if (nDamageCount > 3) + { + // we got blowed up + Blips[enemy.x][enemy.y] = BLIP_DIM; + Blips[player.x][player.y] = BLIP_BRIGHT; + + ArmorBattle_StopSound(); + PaintGame(nScore); + Platform_Pause(500); + + ArmorBattle_ClearScreen(); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_HIT, PLAYSOUNDFLAGS_PRIORITY); + player.x = nPlayerStartX; + player.y = nPlayerStartY; + + if (++nHits >= 10) + { + // too many hits - game over! + + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + + // put the tanks in their starting positions + player.x = nPlayerStartX; + player.y = nPlayerStartY; + } + + bInFrame = FALSE; + return; + } + } + else + { + nDamageCount = 0; + } + } + } + } + + // handle power off, and game over states + if (bPower){ + if (bGameOver) + { + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_DIM; + PaintGame(nScore); + bInFrame = FALSE; + return; + } + } else { + ArmorBattle_ClearScreen(); + bInFrame = FALSE; + return; + } + + // wait for fire button before starting + if (!bGameStarted) + { + // wait to start + + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_DIMBLINK; + + BOOL bChange; + if (ArmorBattle_GetInputFIRE(&bChange)) + { + if (bChange) + { + bGameStarted = TRUE; + } + } + } + else + { + // run the game + + BOOL bHit = FALSE; + + BOOL bChange; + if (ArmorBattle_GetInputLEFT(&bChange)) + { + if (bChange) + { + if (ArmorBattle_GetInputFIRE(NULL)) + { + // fire left + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_OFF; + PaintGame(-1); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_FIRE, PLAYSOUNDFLAGS_PRIORITY); + + // test for a hit + if ((enemy.x == player.x - 1) && (enemy.y == player.y)) + { + bHit = TRUE; + } + + } + else + { + // move left + if (player.x > 0) + { + player.x--; + } + } + } + } + else if (ArmorBattle_GetInputRIGHT(&bChange)) + { + if (bChange) + { + if (ArmorBattle_GetInputFIRE(NULL)) + { + // fire right + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_OFF; + PaintGame(-1); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_FIRE, PLAYSOUNDFLAGS_PRIORITY); + + // test for a hit + if ((enemy.x == player.x + 1) && (enemy.y == player.y)) + { + bHit = TRUE; + } + } + else + { + // move right + if (player.x < (ARMORBATTLE_BLIP_COLUMNS-1)) + { + player.x++; + } + } + } + } + else if (ArmorBattle_GetInputUP(&bChange)) + { + if (bChange) + { + if (ArmorBattle_GetInputFIRE(NULL)) + { + // fire up + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_OFF; + PaintGame(-1); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_FIRE, PLAYSOUNDFLAGS_PRIORITY); + + // test for a hit + if ((enemy.x == player.x) && (enemy.y == player.y - 1)) + { + bHit = TRUE; + } + } + else + { + // move up + if (player.y > 0) + { + player.y--; + } + } + } + } + else if (ArmorBattle_GetInputDOWN(&bChange)) + { + if (bChange) + { + if (ArmorBattle_GetInputFIRE(NULL)) + { + // fire down + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_OFF; + PaintGame(-1); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_FIRE, PLAYSOUNDFLAGS_PRIORITY); + + // test for a hit + if ((enemy.x == player.x) && (enemy.y == player.y + 1)) + { + bHit = TRUE; + } + } + else + { + // move down + if (player.y < (ARMORBATTLE_BLIP_ROWS-1)) + { + player.y++; + } + } + } + } + + if (bHit) + { + // hit an enemy tank + ArmorBattle_StopMineSound(); + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_DIM; + PaintGame(nScore); + + Platform_Pause(250); + + ArmorBattle_ClearScreen(); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_SCORE, PLAYSOUNDFLAGS_PRIORITY); + ++nScore; + + PositionPlayers(); + PlantMines(); + + bGameStarted = FALSE; + + bInFrame = FALSE; + return; + } + + // check for being next to a mine + { + BOOL bNear = FALSE; + for (int i=0; i<3; i++) + { + if (((mines[i].x+1 == player.x) && (mines[i].y == player.y)) + || ((mines[i].x-1 == player.x) && (mines[i].y == player.y)) + || ((mines[i].x == player.x) && (mines[i].y+1 == player.y)) + || ((mines[i].x == player.x) && (mines[i].y-1 == player.y))) + { + bNear = TRUE; + break; + } + } + if (bNear) + { + ArmorBattle_PlayMineSound(); + } + else + { + ArmorBattle_StopMineSound(); + } + + } + + // check for landing on a mine + { + for (int i=0; i<3; i++) + { + if (((mines[i].x == player.x) && (mines[i].y == player.y)) + || ((player.x == enemy.x) && (player.y == enemy.y))) + { + // hit a mine or enemy tank! + Blips[player.x][player.y] = BLIP_BRIGHT; + + ArmorBattle_StopSound(); + PaintGame(nScore); + Platform_Pause(500); + + ArmorBattle_StopMineSound(); + ArmorBattle_ClearScreen(); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_HIT, PLAYSOUNDFLAGS_PRIORITY); + player.x = nPlayerStartX; + player.y = nPlayerStartY; + + if (++nHits >= 10) + { + // too many hits - game over! + ArmorBattle_ClearScreen(); + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + + // put the tanks in their starting positions + player.x = nPlayerStartX; + player.y = nPlayerStartY; + } + + bInFrame = FALSE; + return; + } + } + } + + // tick sound + ArmorBattle_PlaySound(ARMORBATTLE_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + + // update the blips + Blips[player.x][player.y] = BLIP_BRIGHT; + Blips[enemy.x][enemy.y] = BLIP_DIM; + } + + if (bGameStarted) + { + PaintGame(nGameTimer); + } + else + { + PaintGame(nScore); + } + + bInFrame = FALSE; +} + +void PaintGame(int nDisplay) +{ + static int nBlinkCounter = 0; + + Platform_StartDraw(); + + // draw the blips field + for (int y = 0; y < ARMORBATTLE_BLIP_ROWS; y++){ + for (int x = 0; x < ARMORBATTLE_BLIP_COLUMNS; x++) + { + switch(Blips[x][y]){ + case BLIP_OFF: + case BLIP_DIM: + case BLIP_BRIGHT: + ArmorBattle_DrawBlip(Blips[x][y], x, y); + break; + case BLIP_DIMBLINK: + if ((nBlinkCounter % 6 == 1) || (nBlinkCounter % 6 == 3)){ + ArmorBattle_DrawBlip(BLIP_DIM, x, y); + } else { + ArmorBattle_DrawBlip(BLIP_OFF, x, y); + } + break; + } + } + } + + // draw the display + ArmorBattle_DrawTime(nDisplay); + + Platform_EndDraw(); + + ++nBlinkCounter; + +} + + +void PositionPlayers() +{ + // the player is always positioned somewhere on the edge + // pick a random edge + do { + switch(Platform_Random(4)) + { + case 0: + // left side + player.x = 0; + player.y = Platform_Random(ARMORBATTLE_BLIP_ROWS); + break; + case 1: + // top side + player.x = Platform_Random(ARMORBATTLE_BLIP_COLUMNS); + player.y = 0; + break; + case 2: + // right side + player.x = ARMORBATTLE_BLIP_COLUMNS-1; + player.y = Platform_Random(ARMORBATTLE_BLIP_ROWS); + break; + case 3: + // bottom side + player.x = Platform_Random(ARMORBATTLE_BLIP_COLUMNS); + player.y = ARMORBATTLE_BLIP_ROWS-1; + break; + } + } while (player.x == 2); + + // position enemy in opposite quadrant + do { + if (player.x < 2) + { + enemy.x = Platform_Random(3) + 2; + } + else if (player.x > 2) + { + enemy.x = Platform_Random(3); + } + + if (player.y < 2) + { + enemy.y = Platform_Random(2) + 2; + } + else if (player.y >= 2) + { + enemy.y = Platform_Random(2); + } + // keep out of corners + } while (((enemy.x==0) && (enemy.y==0)) + || ((enemy.x==0) && (enemy.y==3)) + || ((enemy.x==4) && (enemy.y==0)) + || ((enemy.x==4) && (enemy.y==3))); + + nPlayerStartX = player.x; + nPlayerStartY = player.y; + +} + +void PlantMines() +{ + int i; + + // clear the mines + for (i=0; i<4; i++) + { + mines[i].x = -1; + mines[i].y = -1; + } + + // pick new random positions + BOOL bTooClose; + do { + + bTooClose = FALSE; + + // scatter mines, keeping off of existing mines, player, and enemy + do { + mines[0].x = Platform_Random(ARMORBATTLE_BLIP_COLUMNS); + mines[0].y = Platform_Random(ARMORBATTLE_BLIP_ROWS); + } while (((mines[0].x == player.x) && (mines[0].y == player.y)) + || ((mines[0].x == enemy.x) && (mines[0].y == enemy.y)) + || ((mines[0].x == mines[1].x) && (mines[0].y == mines[1].y)) + || ((mines[0].x == mines[2].x) && (mines[0].y == mines[2].y)) + || ((mines[0].x == mines[3].x) && (mines[0].y == mines[3].y))); + + do { + mines[1].x = Platform_Random(ARMORBATTLE_BLIP_COLUMNS); + mines[1].y = Platform_Random(ARMORBATTLE_BLIP_ROWS); + } while (((mines[1].x == player.x) && (mines[1].y == player.y)) + || ((mines[1].x == enemy.x) && (mines[1].y == enemy.y)) + || ((mines[1].x == mines[0].x) && (mines[1].y == mines[0].y)) + || ((mines[1].x == mines[2].x) && (mines[1].y == mines[2].y)) + || ((mines[1].x == mines[3].x) && (mines[1].y == mines[3].y))); + + do { + mines[2].x = Platform_Random(ARMORBATTLE_BLIP_COLUMNS); + mines[2].y = Platform_Random(ARMORBATTLE_BLIP_ROWS); + } while (((mines[2].x == player.x) && (mines[2].y == player.y)) + || ((mines[2].x == enemy.x) && (mines[2].y == enemy.y)) + || ((mines[2].x == mines[0].x) && (mines[2].y == mines[0].y)) + || ((mines[2].x == mines[1].x) && (mines[2].y == mines[1].y)) + || ((mines[2].x == mines[3].x) && (mines[2].y == mines[3].y))); + + // make sure there is not a mine right next to the player's + // starting position + for (i=0; i<4; i++) + { + if (((mines[i].x+1 == player.x) && (mines[i].y == player.y)) + || ((mines[i].x-1 == player.x) && (mines[i].y == player.y)) + || ((mines[i].x == player.x) && (mines[i].y+1 == player.y)) + || ((mines[i].x == player.x) && (mines[i].y-1 == player.y))) + { + bTooClose = TRUE; + } + } + + } while (bTooClose); + +} + diff --git a/source/game/ArmorBattle.h b/source/game/ArmorBattle.h new file mode 100644 index 0000000..abdc178 --- /dev/null +++ b/source/game/ArmorBattle.h @@ -0,0 +1,67 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __ARMORBATTLE_H__ +#define __ARMORBATTLE_H__ + +#include "Platform.h" +#include "Platform_armorbattle.h" + + +#define ARMORBATTLE_BLIP_ROWS 4 +#define ARMORBATTLE_BLIP_COLUMNS 5 + +#define ARMORBATTLE_SOUND_TICK 0 +#define ARMORBATTLE_SOUND_NEAR 1 +#define ARMORBATTLE_SOUND_ENEMY 2 +#define ARMORBATTLE_SOUND_FIRE 3 +#define ARMORBATTLE_SOUND_HIT 4 +#define ARMORBATTLE_SOUND_SCORE 5 +#define ARMORBATTLE_SOUND_ENDGAME 6 + +void ArmorBattle_Run(); +void ArmorBattle_SetSkill(int i); +int ArmorBattle_GetSkill(); +void ArmorBattle_PowerOn(); +void ArmorBattle_PowerOff(); +BOOL ArmorBattle_GetPower(); + + +#endif + + + + + diff --git a/source/game/AutoRace.c b/source/game/AutoRace.c new file mode 100644 index 0000000..3807602 --- /dev/null +++ b/source/game/AutoRace.c @@ -0,0 +1,453 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "AutoRace.h" +#include "Games.h" + +// constants + +#define TIMER_CARADVANCE 10 + +typedef int BLIP; + +static BLIP Blips[AUTORACE_BLIP_COLUMNS][AUTORACE_BLIP_ROWS]; + +typedef struct ONCOMINGCAR{ + int nRow; + int nColumn; + BOOL bActive; +}ONCOMINGCAR; + +static ONCOMINGCAR sOncomingCarA, sOncomingCarB; + + +// game variables +static int nLaneSelector; +static int nGear; +static int nCarRow; +static int nGameTimer; +static int nLaps; +static BOOL bGameEnd; // 1 = loose, 2 = win +static BOOL bInFrame = FALSE; +static BOOL bPower; +static int nCarAdvanceTimer; +static int nGearCounter; + +static void fsmPlayStartWait(); +static void fsmInPlay(); +static void fsmCrash(); +static void fsmEndLap(); +static void fsmEndGame(); + +static enum FSM { + FSM_PLAYSTARTWAIT=0, + FSM_INPLAY, + FSM_CRASH, + FSM_ENDLAP, + FSM_ENDGAME +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmPlayStartWait, + fsmInPlay, + fsmCrash, + fsmEndLap, + fsmEndGame +}; + +static void InitGame(); +static void UpdateOurCar(); +static void UpdateOncomingCars(); +static void DoHitTest(); +static void UpdateBlips(); +static void StartSecondCar(); + +BOOL AutoRace_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void AutoRace_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void AutoRace_PowerOff() +{ + bPower = FALSE; + AutoRace_StopSound(); + AutoRace_StopEngineSound(); +} + +int AutoRace_GetSkill() +{ + return nGear; +} + +void AutoRace_SetSkill(int i) +{ + if (i > 3) { + i = 3; + } + else if (i < 0) { + i = 0; + } + nGear = i; +} + +void InitGame() +{ + // set our car's position + nLaneSelector = 1; + nCarRow = AUTORACE_BLIP_ROWS - 1; + + // init the other cars + sOncomingCarA.bActive = FALSE; + sOncomingCarB.bActive = FALSE; + + nGameTimer = 0; + bGameEnd = 0; + nLaps = 0; + + nCarAdvanceTimer = TIMER_CARADVANCE; + nGearCounter = 999; + fsm = FSM_PLAYSTARTWAIT; +} + +void AutoRace_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < AUTORACE_BLIP_ROWS; y++){ + for (x = 0; x < AUTORACE_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + if (!bPower){ + fsm = FSM_PLAYSTARTWAIT; + } + Platform_StartDraw(); + + (fsmfcn[fsm])(); + + UpdateBlips(); + + // draw the blips field + for (int y = 0; y < AUTORACE_BLIP_ROWS; y++){ + for (int x = 0; x < AUTORACE_BLIP_COLUMNS; x++){ + AutoRace_DrawBlip(Blips[x][y], x, y); + } + } + + // draw the score + AutoRace_DrawTime(nGameTimer); + + Platform_EndDraw(); + + bInFrame = FALSE; +} + +void fsmInPlay() +{ + BOOL bMoveCars = FALSE; + + if (Platform_IsNewSecond()){ + // update the game timer + ++nGameTimer; + if (nGameTimer == 99){ + // time's up -- game over! + bGameEnd = 1; + fsm = FSM_ENDGAME; + return; + } + } + + // get the current stick position + nLaneSelector = AutoRace_GetInputSTICK(); + + // check for gear changes + nGear = AutoRace_GetInputGEAR(NULL); + + // move the cars at the correct speed per gear selection + AutoRace_PlayEngineSound(); + + switch(nGear){ + case 0: + if (nGearCounter > 3){ + nGearCounter = 0; + bMoveCars = TRUE; + } + break; + case 1: + if (nGearCounter > 2){ + nGearCounter = 0; + bMoveCars = TRUE; + } + break; + case 2: + if (nGearCounter > 1){ + nGearCounter = 0; + bMoveCars = TRUE; + } + break; + case 3: + // move every frame + bMoveCars = TRUE; + nGearCounter = 0; + break; + } + ++nGearCounter; + + if (bMoveCars){ + UpdateOncomingCars(); + DoHitTest(); + UpdateOurCar(); + DoHitTest(); + } +} + +void UpdateOurCar() +{ + if (nCarAdvanceTimer){ + --nCarAdvanceTimer; + } + if (nCarAdvanceTimer == 0){ + + // move our car up + --nCarRow; + if (nCarRow <= 0){ + // lap completed! + fsm = FSM_ENDLAP; + } + nCarAdvanceTimer = TIMER_CARADVANCE; + } +} + +void UpdateOncomingCars() +{ + + // move the oncoming cars down + for (int i=0; i<2; i++){ + + ONCOMINGCAR *pOncomingCar = i ? &sOncomingCarB : &sOncomingCarA; + + if (pOncomingCar->bActive){ + pOncomingCar->nRow++; + if (pOncomingCar->nRow >= AUTORACE_BLIP_ROWS){ + // car has left the screen + pOncomingCar->bActive = FALSE; + } + } + + } + + // count the number of oncoming cars + // should be at least 1 car at all times + // maximum 2 oncoming cars at any given time + + if (!sOncomingCarA.bActive && !sOncomingCarB.bActive){ + + // no cars are approaching, start at least one + sOncomingCarA.bActive = TRUE; + sOncomingCarA.nRow = -2; + sOncomingCarA.nColumn = Platform_Random(3); + + // and perhaps start a second car + if (Platform_Random(5) == 0){ + StartSecondCar(); + } + + } + + if (!sOncomingCarA.bActive || !sOncomingCarB.bActive){ + // only 1 car is active -- randomly try to start a second car + if (Platform_Random(10) == 0){ + StartSecondCar(); + } + } +} + +void StartSecondCar() +{ + if (sOncomingCarA.bActive && sOncomingCarB.bActive){ + // both cars are already active + return; + } + + ONCOMINGCAR *pNewOncomingCar, *pOtherOncomingCar; + if (sOncomingCarA.bActive){ + pNewOncomingCar = &sOncomingCarB; + pOtherOncomingCar = &sOncomingCarA; + } else { + pNewOncomingCar = &sOncomingCarA; + pOtherOncomingCar = &sOncomingCarB; + } + + pNewOncomingCar->bActive = TRUE; + pNewOncomingCar->nRow = -2; + pNewOncomingCar->nColumn = Platform_Random(3); + + if ((pNewOncomingCar->nColumn == pOtherOncomingCar->nColumn) + && (pNewOncomingCar->nRow == pOtherOncomingCar->nRow) + && pOtherOncomingCar->bActive){ + // car is on top of other car -- reposition the car behind the other car + pNewOncomingCar->nRow = pNewOncomingCar->nRow-1; + } + +} + +void DoHitTest() +{ + for (int i=0; i<2; i++){ + ONCOMINGCAR *pOncomingCar = i ? &sOncomingCarB : &sOncomingCarA; + + if (pOncomingCar->bActive){ + if ((pOncomingCar->nRow == nCarRow) + && (pOncomingCar->nColumn == nLaneSelector)){ + + // hit an oncoming car! + fsm = FSM_CRASH; + if (nCarRow < (AUTORACE_BLIP_ROWS - 1)){ + ++nCarRow; + } + else { + // if oncoming car is in the last row and hits us + // delete it to keep it from hitting us every frame + // (since our car can't be moved out of the way) + pOncomingCar->bActive = FALSE; + } + } + } + } +} + +void UpdateBlips() +{ + // draw the oncoming car blips + for (int i=0; i<2; i++){ + ONCOMINGCAR *pOncomingCar = i ? &sOncomingCarB : &sOncomingCarA; + if (pOncomingCar->bActive){ + if ((pOncomingCar->nColumn >= 0) && (pOncomingCar->nColumn < AUTORACE_BLIP_COLUMNS) + && (pOncomingCar->nRow >= 0) && (pOncomingCar->nRow < AUTORACE_BLIP_ROWS)){ + Blips[pOncomingCar->nColumn][pOncomingCar->nRow] = (fsm == FSM_CRASH) ? BLIP_BRIGHT : BLIP_DIM; + } + else if ((pOncomingCar->nColumn >= 0) && (pOncomingCar->nColumn < AUTORACE_BLIP_COLUMNS) + && (pOncomingCar->nRow == -1)){ + // oncoming car blips display on-screen for an extra frame when they first appear + // (to give you a better chance of avoiding them when our car is near the top) + // put them on-screen even if they are just off-screen + Blips[pOncomingCar->nColumn][0] = (fsm == FSM_CRASH) ? BLIP_BRIGHT : BLIP_DIM; + } + } + } + + // draw the player's car blip + if ((nCarRow <= (AUTORACE_BLIP_ROWS - 1)) + && (nCarRow >= 0)){ + Blips[nLaneSelector][nCarRow] = BLIP_BRIGHT; + } + +} + +void fsmPlayStartWait() +{ + nLaneSelector = AutoRace_GetInputSTICK(); + + // check for gear changes + nGear = AutoRace_GetInputGEAR(NULL); + + if (bPower){ + Blips[nLaneSelector][nCarRow] = BLIP_BRIGHT; + } + else { + AutoRace_ClearScreen(); + } + + // wait for 1st gear before starting + if (nGear == 0){ + Platform_IsNewSecond(); + fsm = FSM_INPLAY; + } +} + +void fsmCrash() +{ + AutoRace_PlaySound(AUTORACE_SOUND_HIT, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_INPLAY; +} + +void fsmEndLap() +{ + // lap completed! + AutoRace_StopEngineSound(); + Platform_Pause(300); + nCarRow = AUTORACE_BLIP_ROWS - 1; + ++nLaps; + if (nLaps >= 4){ + // finished race -- game over! + bGameEnd = 2; + fsm = FSM_ENDGAME; + } + else { + AutoRace_PlayEngineSound(); + fsm = FSM_INPLAY; + } +} + +void fsmEndGame() +{ + AutoRace_ClearScreen(); + AutoRace_StopEngineSound(); + + switch(bGameEnd) { + case 1: + AutoRace_PlaySound(AUTORACE_SOUND_TIME, PLAYSOUNDFLAGS_PRIORITY); + break; + case 2: + AutoRace_PlaySound(AUTORACE_SOUND_WIN, PLAYSOUNDFLAGS_PRIORITY); + break; + default: + break; + } + bGameEnd = 0; +} \ No newline at end of file diff --git a/source/game/AutoRace.h b/source/game/AutoRace.h new file mode 100644 index 0000000..d0e6396 --- /dev/null +++ b/source/game/AutoRace.h @@ -0,0 +1,67 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __AUTORACE_H__ +#define __AUTORACE_H__ + +#include "Platform.h" +#include "Platform_Autorace.h" + + +#define AUTORACE_BLIP_ROWS 7 +#define AUTORACE_BLIP_COLUMNS 3 + +#define AUTORACE_SOUND_GEAR0 0 +#define AUTORACE_SOUND_GEAR1 1 +#define AUTORACE_SOUND_GEAR2 2 +#define AUTORACE_SOUND_GEAR3 3 +#define AUTORACE_SOUND_HIT 4 +#define AUTORACE_SOUND_TIME 5 +#define AUTORACE_SOUND_WIN 6 + +void AutoRace_Run(); +void AutoRace_SetSkill(int i); +int AutoRace_GetSkill(); +void AutoRace_PowerOn(); +void AutoRace_PowerOff(); +BOOL AutoRace_GetPower(); + + +#endif + + + + + diff --git a/source/game/Baseball.c b/source/game/Baseball.c new file mode 100644 index 0000000..8ee85a9 --- /dev/null +++ b/source/game/Baseball.c @@ -0,0 +1,1327 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.comWebsite : http://www.peterhirschberg.com + +*/ + +#include "Baseball.h" +#include "Games.h" + +// constants +#define FIRSTBASE 3 +#define SECONDBASE 6 +#define THIRDBASE 9 +#define HOMEPLATE 12 + + +// game variables +static BOOL bHomeTeam; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bPro2 = FALSE; + +static int nHRuns; +static int nVRuns; +static int nInnings; +static int nOuts; +static int nBalls; +static int nStrikes; + +static int nTimerPitchWait; + +static int nPitchSpeed; +static BOOL bCurveball; +static int nEraseIndex; +static int nPitchIndex; +static int nPendingRuns; + +static int nTimerEndPlayWait; + +static int nTimerRunnerMove; +static int nRunnerSpeed; +static int nTimerFielding; + +static int nCurrentRunnerIndex; + +static int nDefenseBlip; + +static BOOL bCaught; +static int fireWorks; + +// finite state machine stuff + +static void fsmIdle(int tu); +static void fsmPitchWait(int tu); +static void fsmPitching(int tu); +static void fsmEndPlayWait(int tu); +static void fsmRun(int tu); +static void fsmWalk(int tu); +static void fsmOut(int tu); +static void fsmHomeRun(int tu); +static void fsmEndPossession(int tu); +static void fsmGameOver(int tu); + +static enum FSM { + FSM_IDLE, + FSM_PITCHWAIT, + FSM_PITCHING, + FSM_ENDPLAYWAIT, + FSM_RUN, + FSM_WALK, + FSM_OUT, + FSM_HOMERUN, + FSM_ENDPOSSESSION, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(int); + +static FSMFCN fsmfcn[] = { + fsmIdle, + fsmPitchWait, + fsmPitching, + fsmEndPlayWait, + fsmRun, + fsmWalk, + fsmOut, + fsmHomeRun, + fsmEndPossession, + fsmGameOver +}; + +typedef struct RUNNER +{ + int baseindex; + BOOL enabled; +}RUNNER; + +#define MAX_RUNNERS 4 +RUNNER runners[MAX_RUNNERS]; + + +// proto's +static void InitGame(); +static void ClearAllDisplay(); +static void RestoreAllDisplay(); +static void InsertRunner(); +static BOOL MoveRunners(); +static void ResetOffBaseRunners(); +static void DrawDefenseBlip(int index); +static void DrawBaseBlips(BOOL bState); +static void ErasePitchBlips(); +static void HitBall(int nPosition); +static void DoOut(); + +BOOL Baseball_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void Baseball_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void Baseball_PowerOff() +{ + bPower = FALSE; + Baseball_StopSound(); +} + +void Baseball_SetSkill(int i) +{ + if (i == 0) + { + bPro2 = FALSE; + } + else { + bPro2 = TRUE; + } +} + +int Baseball_GetSkill() +{ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + + nHRuns = 0; + nVRuns = 0; + nInnings = 0; + nStrikes = 0; + nOuts = 0; + nBalls = 0; + + for (int i=0; i 0) + { + Baseball_DrawPitchBlip(TRUE, nEraseIndex, bCurveball); + } + DrawBaseBlips(TRUE); + if (nDefenseBlip != -1) + { + DrawDefenseBlip(nDefenseBlip); + } +} + +static void DrawDefenseBlip(int index) +{ + Baseball_DrawDeepBlip((index == 0) ? TRUE:FALSE, 0); + Baseball_DrawOutfieldBlip((index == 1) ? TRUE:FALSE, 0); + Baseball_DrawOutfieldBlip((index == 2) ? TRUE:FALSE, 1); + Baseball_DrawOutfieldBlip((index == 3) ? TRUE:FALSE, 2); + Baseball_DrawDeepBlip((index == 4) ? TRUE:FALSE, 1); +} + +static void DrawBaseBlips(BOOL bState) +{ + if (bState) + { + for (int i=0; i= 0) && (runners[i].baseindex < HOMEPLATE)) + { + // erase previous blip position + Baseball_DrawBaseBlip(FALSE, runners[i].baseindex); + } + runners[i].baseindex++; + if (runners[i].baseindex >= HOMEPLATE) + { + // got a run + runners[i].baseindex=-1; + runners[i].enabled=FALSE; + if (i == nCurrentRunnerIndex) + { + nCurrentRunnerIndex = -1; + } + bRun=TRUE; + } + } + } + + return bRun; +} + +static void ResetOffBaseRunners() +{ + BOOL bOffBase = FALSE; + for (int i=0; i runners[nRunnerOut].baseindex) + { + nRunnerOut = i; + } + } + } + } + // mark the lead runner out + if (nRunnerOut != -1) + { + runners[nRunnerOut].enabled = FALSE; + } + + // figure out if the remaining runners should go to the previous or next base + for (i=0; i 0) + { + Baseball_PlaySound(BASEBALL_SOUND_RUN, PLAYSOUNDFLAGS_ASYNC|PLAYSOUNDFLAGS_PRIORITY); + Platform_Pause(600); + --nPendingRuns; + } + + nOuts = 0; + bHomeTeam = !bHomeTeam; + if (!bHomeTeam) + { + ++nInnings; + if (nInnings == 5) + { + // ************************ + // ****** GAME OVER ******* + // ************************ + Baseball_PlaySound(BASEBALL_SOUND_ENDGAME, PLAYSOUNDFLAGS_ASYNC|PLAYSOUNDFLAGS_PRIORITY); + Platform_Pause(200); + fsm = FSM_GAMEOVER; + return; + } + } + PlatformSetInput(bHomeTeam); + Baseball_PlaySound(BASEBALL_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + RestoreAllDisplay(); + Baseball_DrawStats(-1, -1, nBalls, nStrikes, bHomeTeam); + fsm = FSM_ENDPOSSESSION; + } + else + { + RestoreAllDisplay(); + Baseball_DrawStats(-1, -1, nBalls, nStrikes, bHomeTeam); + nTimerEndPlayWait = (nDefenseBlip == -1) ? (1500/50) : (3000/50); + fsm = FSM_ENDPLAYWAIT; + } + nStrikes = 0; + nBalls = 0; +} + + +// FINITE STATE MACHINE STUFF + +static void fsmIdle(int tu) +{ + // play the run sounds + while(nPendingRuns > 0) + { + Baseball_PlaySound(BASEBALL_SOUND_RUN, PLAYSOUNDFLAGS_ASYNC|PLAYSOUNDFLAGS_PRIORITY); + Platform_Pause(600); + --nPendingRuns; + } + + nCurrentRunnerIndex = -1; + nDefenseBlip = -1; + bCaught = FALSE; + + if (Baseball_GetInputSCORE(NULL)) + { + Baseball_DrawScore(nVRuns, nHRuns); + } + else + { + Baseball_DrawStats(nInnings+1, nOuts, nBalls, nStrikes, bHomeTeam); + } + + // wait for pitch button + if (Baseball_GetInputPITCH(NULL)) + { + // delay from 1.5 to 2.5 seconds (according to manual) + // before pitching the ball + + // access of game context info from here is probably not too cool + nTimerPitchWait = (Platform_Random(1000) + 1500) / gGameContext[GAME_BASEBALL].tu; + fsm = FSM_PITCHWAIT; + } + Baseball_DrawBaseBlip(FALSE, 0); + DrawBaseBlips(TRUE); +} + +static void fsmPitchWait(int tu) +{ + Baseball_DrawScore(-1, -1); + + if (nTimerPitchWait > 0) + { + --nTimerPitchWait; + } + + if (nTimerPitchWait <= 0) + { + // pick a ball speed and throw style + // and pitch the ball + bCurveball = (Platform_Random(3) == 0) ? TRUE : FALSE; + if (bCurveball) + { + nPitchSpeed = Platform_Random(2)+1; // curve balls are a little slower + } + else + { + nPitchSpeed = Platform_Random(3); + } + +#ifdef __PALMOS__ + nPitchSpeed += 7; // PALMOS ONLY +#endif + + nPitchIndex = -1; + fsm = FSM_PITCHING; + } +} + +static void fsmPitching(int tu) +{ + BOOL bStrike = FALSE; + static int nswing; // swing early=0, center=1, late=2 + int nMissChance = 5; + + if(nPitchIndex == -1) { + Baseball_DrawScore(-1, -1); + nEraseIndex = -1; + nPitchIndex = 0; + nswing = 0; + } + + if(nPitchIndex <= 8) + { + if (nEraseIndex != -1) + { + Baseball_DrawPitchBlip(FALSE, nEraseIndex, bCurveball); + } + + Baseball_DrawPitchBlip(TRUE, nPitchIndex, bCurveball); + nEraseIndex = nPitchIndex; + + // check for swing at 3 different points + // we really only need to check 3 times + // when the ball is in the strike zone, but + // we'll do it anyway to keep the timing consistant + + // see HitBall() function for detailed description + // of what it does and what the parameter means + + if (Baseball_GetInputHIT(NULL)) + { + // swing early + switch (nPitchIndex) + { + case 5: + if (Platform_Random(nMissChance)==0) + { + // missed + bStrike = TRUE; + break; + } + else + { + HitBall(0+nswing); + return; + } + case 6: + if (Platform_Random(nMissChance)==0) + { + // missed + bStrike = TRUE; + break; + } + else + { + HitBall(3+nswing); + return; + } + case 7: + if (Platform_Random(nMissChance)==0) + { + // missed + bStrike = TRUE; + break; + } + else + { + HitBall(6+nswing); + return; + } + default: + // strike + bStrike = TRUE; + break; + } + } + + if (!bStrike) { + int nDelay = ((nPitchSpeed * 4) / 3) - tu; + + if(nDelay > 0) + Platform_Pause(nDelay); + nswing++; + if(nswing == 3) { + nPitchIndex++; + nswing = 0; + } + } + else { + nPitchIndex = 9; + } + } + + if(nPitchIndex >= 9) { + Platform_Pause(200); + + // if player didn't swing, randomly pick strike or ball + if (Platform_Random(2) && !bStrike) + { + ++nBalls; + } + else + { + ++nStrikes; + } + + if (nBalls == 4) + { + // walk + Baseball_DrawStats(-1, -1, nBalls, nStrikes, bHomeTeam); + Baseball_PlaySound(BASEBALL_SOUND_STRIKE, PLAYSOUNDFLAGS_PRIORITY); + nTimerEndPlayWait = 1500/50; + nTimerRunnerMove = nRunnerSpeed = 10; // walk is always a set speed + InsertRunner(); + fsm = FSM_WALK; + } + else if (nStrikes == 3) + { + // struck out + DoOut(); + } + else + { + Baseball_DrawStats(-1, -1, nBalls, nStrikes, bHomeTeam); + Baseball_PlaySound(BASEBALL_SOUND_STRIKE, PLAYSOUNDFLAGS_PRIORITY); + nTimerEndPlayWait = 1500/50; + fsm = FSM_ENDPLAYWAIT; + } + } +} + +static void fsmEndPlayWait(int tu) +{ + if (nTimerEndPlayWait > 0) + { + --nTimerEndPlayWait; + if (nDefenseBlip != -1) + { + // blink fielder if one caught a ball + if (bCaught) + { + static BOOL blink=FALSE; + static int blinkcnt=0; + --blinkcnt; + if (blinkcnt<0) + { + blinkcnt=2; + blink=!blink; + } + if (blink) + { + DrawDefenseBlip(nDefenseBlip); + } + else + { + DrawDefenseBlip(-1); + } + } + else + { + DrawDefenseBlip(nDefenseBlip); + } + } + } + else + { + // erase the old blips + Baseball_DrawPitchBlip(FALSE, nEraseIndex, bCurveball); + DrawDefenseBlip(-1); + ErasePitchBlips(); + + // reset the runners + ResetOffBaseRunners(); + DrawBaseBlips(FALSE); + + fsm = FSM_IDLE; + } +} + +static void fsmRun(int tu) +{ + DrawBaseBlips(TRUE); + + // RUN does not take effect until you release HIT + if (Baseball_GetInputRUN(NULL) && !Baseball_GetInputHIT(NULL)) + { + if (nTimerRunnerMove > 0) + { + --nTimerRunnerMove; + } + if (nTimerRunnerMove == 0) + { + nTimerRunnerMove = nRunnerSpeed; + if (MoveRunners()) + { + // record runs + if (bHomeTeam) + { + ++nHRuns; + } + else + { + ++nVRuns; + } + // also note the run for later (for the sounds) + ++nPendingRuns; + } + } + } + + if (nTimerFielding > 0) + { + --nTimerFielding; + } + if (nTimerFielding == 0) + { + // ball is finished being fielded + + // erase the fielder's blip +// nDefenseBlip = -1; +// DrawDefenseBlip(-1); + + // ball has been fielded - see if any runners are off base + BOOL bOffBase = FALSE; + for (int i=0; i 0) + { + --nTimerRunnerMove; + } + if (nTimerRunnerMove == 0) + { + nTimerRunnerMove = nRunnerSpeed; + if (MoveRunners()) + { + // record runs + if (bHomeTeam) + { + ++nHRuns; + } + else + { + ++nVRuns; + } + // also note the run for later (for the sounds) + ++nPendingRuns; + } + + // when the current runner gets on first, we're done + if (runners[nCurrentRunnerIndex].baseindex == FIRSTBASE) + { + // got someone on first - all done + nStrikes = 0; + nBalls = 0; + Baseball_DrawPitchBlip(FALSE, 8, FALSE); + DrawDefenseBlip(-1); + ErasePitchBlips(); + fsm = FSM_IDLE; + } + } + } +} + +static void fsmHomeRun(int tu) +{ + static int loop = 0; + + trace = fireWorks; + if(fireWorks > 0) { + // + // do fireworks display + // + Platform_Pause(40); + ClearAllDisplay(); + + switch(fireWorks) { + case 1: // base and fielder blips + Baseball_PlaySound(BASEBALL_SOUND_RUN, PLAYSOUNDFLAGS_PRIORITY|PLAYSOUNDFLAGS_ASYNC); + Baseball_DrawBaseBlip(TRUE,1); + break; + case 2: + Baseball_DrawBaseBlip(TRUE,1); + Baseball_DrawBaseBlip(TRUE,2); + break; + case 3: + Baseball_DrawBaseBlip(TRUE,1); + Baseball_DrawBaseBlip(TRUE,2); + Baseball_DrawDeepBlip(TRUE,0); + break; + case 4: + Baseball_DrawBaseBlip(TRUE,2); + Baseball_DrawDeepBlip(TRUE,0); + Baseball_DrawBaseBlip(TRUE,4); + break; + case 5: + Baseball_DrawDeepBlip(TRUE,0); + Baseball_DrawBaseBlip(TRUE,4); + Baseball_DrawBaseBlip(TRUE,5); + break; + case 6: + Baseball_DrawBaseBlip(TRUE,4); + Baseball_DrawBaseBlip(TRUE,5); + Baseball_DrawDeepBlip(TRUE,1); + break; + case 7: + Baseball_DrawBaseBlip(TRUE,5); + Baseball_DrawDeepBlip(TRUE,1); + Baseball_DrawBaseBlip(TRUE,8); + break; + case 8: + Baseball_DrawDeepBlip(TRUE,1); + Baseball_DrawBaseBlip(TRUE,8); + Baseball_DrawBaseBlip(TRUE,7); + break; + case 9: + Baseball_DrawBaseBlip(TRUE,8); + Baseball_DrawBaseBlip(TRUE,7); + Baseball_DrawOutfieldBlip(TRUE,0); + break; + case 10: + Baseball_DrawBaseBlip(TRUE,7); + Baseball_DrawOutfieldBlip(TRUE,0); + Baseball_DrawOutfieldBlip(TRUE,1); + break; + case 11: + Baseball_DrawOutfieldBlip(TRUE,0); + Baseball_DrawOutfieldBlip(TRUE,1); + Baseball_DrawFireWorks(); + break; + case 12: + Baseball_DrawOutfieldBlip(TRUE,1); + Baseball_DrawFireWorks(); + Baseball_DrawBaseBlip(TRUE,10); + break; + case 13: + Baseball_DrawFireWorks(); + Baseball_DrawBaseBlip(TRUE,10); + Baseball_DrawBaseBlip(TRUE,11); + break; + case 14: + Baseball_DrawBaseBlip(TRUE,10); + Baseball_DrawBaseBlip(TRUE,11); + Baseball_DrawPitchBlip(TRUE, 8, FALSE); + break; + case 15: + Baseball_DrawPitchBlip(TRUE, 8, FALSE); + Baseball_DrawPitchBlip(TRUE, 7, FALSE); + break; + case 16: + Baseball_DrawPitchBlip(TRUE, 8, FALSE); + Baseball_DrawPitchBlip(TRUE, 7, FALSE); + Baseball_DrawPitchBlip(TRUE, 6, FALSE); + break; + case 17: + Baseball_DrawPitchBlip(TRUE, 7, FALSE); + Baseball_DrawPitchBlip(TRUE, 6, FALSE); + Baseball_DrawPitchBlip(TRUE, 5, FALSE); + break; + case 18: + Baseball_DrawPitchBlip(TRUE, 6, FALSE); + Baseball_DrawPitchBlip(TRUE, 5, FALSE); + Baseball_DrawPitchBlip(TRUE, 4, TRUE); + break; + case 19: + Baseball_DrawPitchBlip(TRUE, 5, FALSE); + Baseball_DrawPitchBlip(TRUE, 3, TRUE); + Baseball_DrawPitchBlip(TRUE, 2, TRUE); + break; + case 20: + Baseball_DrawPitchBlip(TRUE, 3, TRUE); + Baseball_DrawPitchBlip(TRUE, 2, TRUE); + Baseball_DrawPitchBlip(TRUE, 1, TRUE); + break; + case 21: + Baseball_DrawPitchBlip(TRUE, 2, TRUE); + Baseball_DrawPitchBlip(TRUE, 1, TRUE); + Baseball_DrawPitchBlip(TRUE, 1, FALSE); + break; + case 22: + Baseball_DrawPitchBlip(TRUE, 1, TRUE); + Baseball_DrawPitchBlip(TRUE, 1, FALSE); + Baseball_DrawPitchBlip(TRUE, 2, FALSE); + break; + case 23: + Baseball_DrawPitchBlip(TRUE, 1, FALSE); + Baseball_DrawPitchBlip(TRUE, 2, FALSE); + Baseball_DrawPitchBlip(TRUE, 3, FALSE); + break; + case 24: + Baseball_DrawPitchBlip(TRUE, 2, FALSE); + Baseball_DrawPitchBlip(TRUE, 3, FALSE); + Baseball_DrawPitchBlip(TRUE, 4, FALSE); + break; + case 25: + Baseball_DrawPitchBlip(TRUE, 3, FALSE); + Baseball_DrawPitchBlip(TRUE, 4, FALSE); + break; + case 26: + break; + } + + fireWorks++; + if(fireWorks > 26) { + loop++; + if(loop == 4) { + loop = 0; + fireWorks = 0; + // insert a runner + InsertRunner(); + nTimerRunnerMove = nRunnerSpeed = 10; // fixed run speed + } + else { + fireWorks = 1; + } + } + return; + } + + DrawBaseBlips(TRUE); + + Baseball_DrawBaseBlip(TRUE, 0); + + if (Baseball_GetInputRUN(NULL)) + { + if (nTimerRunnerMove > 0) + { + --nTimerRunnerMove; + } + if (nTimerRunnerMove == 0) + { + nTimerRunnerMove = nRunnerSpeed; + if (MoveRunners()) + { + // record runs + if (bHomeTeam) + { + ++nHRuns; + } + else + { + ++nVRuns; + } + // also note the run for later (for the sounds) + ++nPendingRuns; + + // see if anyone is still running the bases + BOOL bManOnBase = FALSE; + for (int i=0; i BASKETBALL_BLIP_COLUMNS-1) \ + || (p.nColumn < 0) \ + || (p.nRow > BASKETBALL_BLIP_ROWS-1) \ + || (p.nRow < 0)) + + +#define ISPLAYERENABLED(p) \ + (p.nBright) + + + +// finite state machine stuff + +static void fsmPlayStartWait(); +static void fsmShowStats(); +static void fsmInPlay(); +static void fsmDunk(); +static void fsmGameOver(); + + +static enum FSM { + FSM_PLAYSTARTWAIT=0, + FSM_SHOWSTATS, + FSM_INPLAY, + FSM_DUNK, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmPlayStartWait, + fsmShowStats, + fsmInPlay, + fsmDunk, + fsmGameOver +}; + + +// proto's +static void InitGame(); +static void DrawBlips(); +static void EraseBlips(); + + +BOOL Basketball_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void Basketball_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void Basketball_PowerOff() +{ + bPower = FALSE; + Basketball_StopSound(); +} + +void Basketball_SetSkill(int i){ + if (i == 0){ + bPro2 = FALSE; + } else { + bPro2 = TRUE; + } +} + +int Basketball_GetSkill(){ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + + nHScore = 0; + nVScore = 0; + fGameTime = 12.0; + nQuarter = 0; + bGameOver = FALSE; + bDeflect = FALSE; + + fsm = FSM_PLAYSTARTWAIT; +} + +void Basketball_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < BASKETBALL_BLIP_ROWS; y++){ + for (x = 0; x < BASKETBALL_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + if (!bPower){ + Basketball_ClearScreen(); + bInFrame = FALSE; + return; + } + + Platform_StartDraw(); + + (fsmfcn[fsm])(); + + DrawBlips(); + + Platform_EndDraw(); + + bInFrame = FALSE; + +} + +void DrawBlips() +{ + int x, y, nBright; + static BOOL bBlink = FALSE; + + if(fsm != FSM_DUNK) { + for (int i=0; i 0) + && (!ISOCCUPIED(player.nColumn-1, player.nRow))){ + MOVEPLAYERLEFT(player); + } + } + } + else if (Basketball_GetInputRIGHT(&bChange)) + { + if (bChange) + { + if ((player.nColumn < (BASKETBALL_BLIP_COLUMNS-1)) + && (!ISOCCUPIED(player.nColumn+1, player.nRow))){ + MOVEPLAYERRIGHT(player); + } + } + } + else if (Basketball_GetInputUP(&bChange)) + { + if (bChange) + { + if ((player.nRow > 0) + && (!ISOCCUPIED(player.nColumn, player.nRow-1))){ + MOVEPLAYERUP(player); + } + } + } + else if (Basketball_GetInputDOWN(&bChange)) + { + if (bChange) + { + if ((player.nRow < (BASKETBALL_BLIP_ROWS-1)) + && (!ISOCCUPIED(player.nColumn, player.nRow+1))){ + MOVEPLAYERDOWN(player); + } + } + } + + if (nTimerDeflect) + { + // still in deflect + --nTimerDeflect; + return; + } + + if (Basketball_GetInputTHROW(&bChange)) + { + if (bChange) + { + if (!ISPLAYERENABLED(ball)) + { + // shoot! + bShoot = TRUE; + nTimerBallMove = TIME_BALLMOVE; + SETPLAYERBRIGHTNESS(player, BLIP_DIMBLINK); + SETPLAYER(ball, player.nColumn, player.nRow, BLIP_BRIGHT); + + if (player.nRow > 0) + { + nBallDirectionY = -1; + } + else + { + nBallDirectionY = 0; + } + + if (player.nColumn < 2) + { + nBallDirectionX = 1; + } + else if (player.nColumn > 2) + { + nBallDirectionX = -1; + } + else + { + nBallDirectionX = 0; + } + } + } + } + + // move the two end defenders randomly + { + if (Platform_Random(bPro2 ? 10 : 20) == 0){ + // move horizontally or vertically + int x = defense[0].nColumn; + int y = defense[0].nRow; + if (Platform_Random(2)){ + if (x == 0){ + x = 1; + } else { + x = 0; + } + } else { + if (y == 0){ + y = 1; + } else { + y = 0; + } + } + if (!ISOCCUPIED(x,y)){ + SETPLAYER(defense[0], x, y, BLIP_DIM); + } + } + if (Platform_Random(bPro2 ? 10 : 20) == 0){ + // move horizontally or vertically + int x = defense[1].nColumn; + int y = defense[1].nRow; + if (Platform_Random(2)){ + if (x == (BASKETBALL_BLIP_COLUMNS-1)){ + x = (BASKETBALL_BLIP_COLUMNS-2); + } else { + x = (BASKETBALL_BLIP_COLUMNS-1); + } + } else { + if (y == 0){ + y = 1; + } else { + y = 0; + } + } + if (!ISOCCUPIED(x,y)) + { + SETPLAYER(defense[1], x, y, BLIP_DIM); + } + } + } + + // there is a peculiar behavior with the game where if + // the player is anywhere in the 2nd to last row, the + // middle defenders line up in their formation positions + // don't know if this was intentional or not, but this + // behavior is reproduced here + + if (player.nRow == (BASKETBALL_BLIP_ROWS - 2)) + { + if (Platform_Random(bPro2 ? 1 : 3) == 0) + { + // pick a random defender + static int nDefenderLast = -1; + int nDefender = Platform_Random(3); + + if (nDefender != nDefenderLast) + { + nDefenderLast = nDefender; + + PLAYER *pDefender; + int ox, oy; + switch(nDefender) + { + case 0: + pDefender = &defense[2]; + ox = 1; + oy = 1; + break; + case 1: + pDefender = &defense[3]; + ox = 2; + oy = 1; + break; + case 2: + pDefender = &defense[4]; + ox = 3; + oy = 1; + break; + } + + int dx = pDefender->nColumn; + int dy = pDefender->nRow; + + // randomly move the defender towards its formation position + if (Platform_Random(2)) + { + if (dx < ox) + { + ++dx; + } + else if (dx > ox) + { + --dx; + } + } + else + { + if (dy < oy) + { + ++dy; + } + else if (dy > oy) + { + --dy; + } + } + + // make sure the defender does not step on anybody, + // and keep him confined to the proper area + if (!ISOCCUPIED(dx, dy) + && (dx > 0) + && (dx < (BASKETBALL_BLIP_COLUMNS - 1)) + && (dy >= 0) + && (dy < (BASKETBALL_BLIP_ROWS - 1))) + { + SETPLAYER((*pDefender), dx, dy, BLIP_DIM); + } + + + } + } + } + else + { + // middle defenders try to roughly occupy the + // midpoint between the ball and the basket + int midx; + int midy; + if (ISPLAYERENABLED(ball)) + { + midx = (ball.nColumn + 2) / 2; + midy = (ball.nRow + 1) / 2; + } + else + { + midx = (player.nColumn + 2) / 2; + midy = (player.nRow + 1) / 2; + } + + // decide if a defender will move this frame - + if (Platform_Random(bPro2 ? 2 : 5) == 0) + { + // pick a random defender + static int nDefenderLast = -1; + int nDefender = Platform_Random(3); + + if (nDefender != nDefenderLast) + { + nDefenderLast = nDefender; + + PLAYER *pDefender; + switch(nDefender) + { + case 0: + pDefender = &defense[2]; + break; + case 1: + pDefender = &defense[3]; + break; + case 2: + pDefender = &defense[4]; + break; + } + + int dx = pDefender->nColumn; + int dy = pDefender->nRow; + + // randomly move the defender towards the midpoint + if (Platform_Random(2)) + { + if (dx < midx) + { + ++dx; + } + else if (dx > midx) + { + --dx; + } + } + else + { + if (dy < midy) + { + ++dy; + } + else if (dy > midy) + { + --dy; + } + } + + // occasionally randomly offset the defender's position + if (Platform_Random(5) == 0) + { + if (Platform_Random(2)) + { + dx += (Platform_Random(2)) ? 1 : -1; + } + else + { + dy += (Platform_Random(2)) ? 1 : -1; + } + } + + // make sure the defender does not step on anybody, + // and keep him confined to the proper area + if (!ISOCCUPIED(dx, dy) + && (dx > 0) + && (dx < (BASKETBALL_BLIP_COLUMNS - 1)) + && (dy >= 0) + && (dy < (BASKETBALL_BLIP_ROWS - 1))) + { + SETPLAYER((*pDefender), dx, dy, BLIP_DIM); + } + + + } + } + } + + // move the ball + if (ISPLAYERENABLED(ball)) + { + // the puck hit a defender last frame - play the sound + if (ISDEFENSE(ball.nColumn, ball.nRow) && !bDeflect) + { + bDeflect = TRUE; + Basketball_PlaySound(BASKETBALL_SOUND_BOUNCE, PLAYSOUNDFLAGS_PRIORITY); + nTimerDeflect = TIME_DEFLECT; + return; + } + + if (--nTimerBallMove <= 0) + { + nTimerBallMove = TIME_BALLMOVE; + + // check for a basket + if ((ball.nColumn == 2) && (ball.nRow == 0) + && !ISDEFENSE(ball.nColumn, ball.nRow)) // <-- is this right? + { + // basket! + ball.nRow = -1; + Basketball_DrawBasket(TRUE); + fsm = FSM_DUNK; + return; + } + + // bounce the ball off the far wall + if (!ISDEFENSE(ball.nColumn, ball.nRow)) + { + if ((ball.nRow <= 0) && (nBallDirectionY == -1)) + { + ball.nRow = 0; + nBallDirectionY = 1; + Basketball_PlaySound(BASKETBALL_SOUND_BOUNCE, PLAYSOUNDFLAGS_PRIORITY); + nTimerDeflect = TIME_DEFLECT; + bDeflect = FALSE; + return; + } + } + + // bounce the ball off the defenders + if (bDeflect) + { + nBallDirectionX = Platform_Random(3) - 1; + nBallDirectionY = 1; + bDeflect = FALSE; + } + + // see if player has regained possession + if (ISPLAYER(ball.nColumn, ball.nRow) && !bShoot) + { + UNSETPLAYER(ball); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + } + else + { + // move the ball + ball.nColumn += nBallDirectionX; + ball.nRow += nBallDirectionY; + bShoot = FALSE; + + // see if the ball bounced off the screen + if (ISPLAYEROFFSCREEN(ball) && ISPLAYERENABLED(ball)) + { + // off the screen - get rid of it and end the play + bShoot = FALSE; + UNSETPLAYER(ball); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + Basketball_ClearScreen(); + Basketball_PlaySound(BASKETBALL_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + } + } + + // count down the clock + if (Platform_IsNewSecond()){ + // check for end of quarter + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime < 0.1){ + + // end of quarter + + ++nQuarter; + if (nQuarter == 4) + { + // game over + bGameOver = TRUE; + + // show formation + { + SETPLAYER(player, 4, 3, BLIP_BRIGHT); + UNSETPLAYER(ball); + SETPLAYER(defense[0], 0, 0, BLIP_DIM); + SETPLAYER(defense[1], 4, 0, BLIP_DIM); + SETPLAYER(defense[2], 1, 1, BLIP_DIM); + SETPLAYER(defense[3], 2, 1, BLIP_DIM); + SETPLAYER(defense[4], 3, 1, BLIP_DIM); + } + + Basketball_ClearScreen(); + Basketball_PlaySound(BASKETBALL_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + else + { + // VERIFY THIS AGAINST THE INSTRUCTION MANUAL + bHomeTeam = (nQuarter % 2) ? FALSE : TRUE; + PlatformSetInput(bHomeTeam); + } + + fGameTime = 12.0; + Basketball_ClearScreen(); + Basketball_PlaySound(BASKETBALL_SOUND_ENDQUARTER, PLAYSOUNDFLAGS_PRIORITY); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + // check for end of play timer + if (--nPlayTime < 0){ + Basketball_ClearScreen(); + Basketball_PlaySound(BASKETBALL_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + + Basketball_DrawStat(nPlayTime); + + // make tick sounds + if (fGameTime >= .1){ + if (--nTimerTickTimer <= 0){ + Basketball_PlaySound(BASKETBALL_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + nTimerTickTimer = bPro2 ? TIME_TICKTIMERPRO2 : TIME_TICKTIMERPRO1; + } + } +} + +void fsmDunk() +{ + Basketball_PlaySound(BASKETBALL_SOUND_SCORE, PLAYSOUNDFLAGS_PRIORITY); + Basketball_DrawBasket(FALSE); + if (bHomeTeam) + { + nHScore += 2; + } + else + { + nVScore += 2; + } + // reset formation + { + SETPLAYER(player, ((bHomeTeam) ? 0 : 4), 3, BLIP_BRIGHT); + UNSETPLAYER(ball); + SETPLAYER(defense[0], 0, 0, BLIP_DIM); + SETPLAYER(defense[1], 4, 0, BLIP_DIM); + SETPLAYER(defense[2], 1, 1, BLIP_DIM); + SETPLAYER(defense[3], 2, 1, BLIP_DIM); + SETPLAYER(defense[4], 3, 1, BLIP_DIM); + } + Platform_IsNewSecond(); + fsm = FSM_INPLAY; +} + +void fsmGameOver() +{ + // show stats if pressed 'down' + BOOL bChange; + if (Basketball_GetInputDOWN(&bChange)) + { + if (bChange) + { + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + fsmShowStats(); + return; + } + } + + Basketball_DrawStat(0); +} + diff --git a/source/game/Basketball.h b/source/game/Basketball.h new file mode 100644 index 0000000..8fae308 --- /dev/null +++ b/source/game/Basketball.h @@ -0,0 +1,62 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __BASKETBALL_H__ +#define __BASKETBALL_H__ + +#include "Platform.h" +#include "Platform_Basketball.h" + +#define BASKETBALL_BLIP_ROWS 4 +#define BASKETBALL_BLIP_COLUMNS 5 + +#define BASKETBALL_SOUND_TICK 0 +#define BASKETBALL_SOUND_BOUNCE 1 +#define BASKETBALL_SOUND_SCORE 2 +#define BASKETBALL_SOUND_ENDPLAY 3 +#define BASKETBALL_SOUND_ENDQUARTER 4 +#define BASKETBALL_SOUND_ENDGAME 5 + +void Basketball_Run(); +void Basketball_SetSkill(int i); +int Basketball_GetSkill(); +void Basketball_PowerOn(); +void Basketball_PowerOff(); +BOOL Basketball_GetPower(); + + +#endif + diff --git a/source/game/Football.c b/source/game/Football.c new file mode 100644 index 0000000..7892d9a --- /dev/null +++ b/source/game/Football.c @@ -0,0 +1,809 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#include "Football.h" +#include "Games.h" + +// constants + +#define NUM_DEFENSEPLAYERS 5 +#define MAX_YARD 100 + +typedef int BLIP; + +static BLIP Blips[FOOTBALL_BLIP_COLUMNS][FOOTBALL_BLIP_ROWS]; + +// game variables +static BOOL bHomeTeam; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bPro2 = FALSE; +static BOOL bGotFirstDown; + +static BOOL bDisplayScore; +static BOOL bDisplayTime; +static BOOL bDisplayYard; +static BOOL bDisplayDown; +static BOOL bDisplayBlips; + +static int nHScore; +static int nVScore; +static float fGameTime; +static int nFirstDownYard; +static int nDown; +static int nQuarter; +static int nCurrentYardline; + +typedef struct PLAYER { + int nYard; + int nColumn; + int nLane; + int nBright; + + int nColumnOld; + int nLaneOld; + int nYardOld; +}PLAYER; + +static PLAYER ball; +static PLAYER player[NUM_DEFENSEPLAYERS]; + +// macros for dealing with the players + +#define TRANSLATE_COLUMN(x) \ + (!bHomeTeam ? x : (FOOTBALL_BLIP_COLUMNS - 1) - x) + +#define UNTRANSLATE_COLUMN(x) \ + (bHomeTeam ? x : (FOOTBALL_BLIP_COLUMNS - 1) - x) + +#define TRANSLATE_YARD(x) \ + (!bHomeTeam ? x : (MAX_YARD - x)) + +#define SETPLAYERBRIGHTNESS(p,b) { \ + p.nBright = b; \ +} + +#define NOTECURRENTPLAYERPOSITION(p) { \ + p.nColumnOld = p.nColumn; \ + p.nLaneOld = p.nLane; \ + p.nYardOld = p.nYard; \ +} + +#define SETPLAYER(p,a,x,y,b) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard = a; \ + p.nColumn = TRANSLATE_COLUMN(x); \ + p.nLane = y; \ + p.nBright = b; \ +} + +#define UNSETPLAYER(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard = -1; \ + p.nColumn = -1; \ + p.nLane = -1; \ + p.nBright = BLIP_OFF; \ +} + +#define MOVEPLAYERUP(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nLane--; \ +} +#define MOVEPLAYERDOWN(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nLane++; \ +} +#define MOVEPLAYERLEFT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn--; \ + if (p.nColumn < 0){ \ + p.nColumn = FOOTBALL_BLIP_COLUMNS-1; \ + } \ + if (!bHomeTeam){ \ + p.nYard--; \ + } else { \ + p.nYard++; \ + } \ +} +#define MOVEPLAYERRIGHT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn++; \ + if (p.nColumn >= FOOTBALL_BLIP_COLUMNS){ \ + p.nColumn = 0; \ + } \ + if (!bHomeTeam){ \ + p.nYard++; \ + } else { \ + p.nYard--; \ + } \ +} +#define MOVEPLAYERDOWNFIELD(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard--; \ + if (bHomeTeam){ \ + p.nColumn++; \ + if (p.nColumn >= FOOTBALL_BLIP_COLUMNS){ \ + p.nColumn = 0; \ + } \ + } else { \ + p.nColumn--; \ + if (p.nColumn < 0){ \ + p.nColumn = FOOTBALL_BLIP_COLUMNS-1; \ + } \ + } \ +} +#define MOVEPLAYERUPFIELD(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard++; \ + if (!bHomeTeam){ \ + p.nColumn++; \ + if (p.nColumn >= FOOTBALL_BLIP_COLUMNS){ \ + p.nColumn = 0; \ + } \ + } else { \ + p.nColumn--; \ + if (p.nColumn < 0){ \ + p.nColumn = FOOTBALL_BLIP_COLUMNS-1; \ + } \ + } \ +} + +static BOOL ISBALL(int x, int y); +static BOOL ISBALL(int x, int y) +{ + if ((ball.nColumn == x) + && (ball.nLane == y) + && (ball.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISDEFENSE(int x, int y); +static BOOL ISDEFENSE(int x, int y) +{ + for (int i=0; i FOOTBALL_BLIP_COLUMNS-1) || (p.nColumn < 0)) + + + +// finite state machine stuff + +static void fsmFormation(); +static void fsmInPlay(); +static void fsmPlayEnded(); +static void fsmGameOver(); + +static enum FSM { + FSM_FORMATION, + FSM_INPLAY, + FSM_PLAYENDED, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmFormation, + fsmInPlay, + fsmPlayEnded, + fsmGameOver +}; + + +// proto's +static void InitGame(); +static void DrawBlips(); +static void EraseBlips(); + + +BOOL Football_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void Football_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void Football_PowerOff() +{ + bPower = FALSE; + Football_StopSound(); +} + +void Football_SetSkill(int i){ + if (i == 0){ + bPro2 = FALSE; + } else { + bPro2 = TRUE; + } +} + +int Football_GetSkill(){ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = TRUE; + PlatformSetInput(bHomeTeam); + + nHScore = 0; + nVScore = 0; + fGameTime = 15.0; + nDown = 0; + nQuarter = 0; + nCurrentYardline = 100 - 20; + nFirstDownYard = nCurrentYardline - 10; + + bDisplayScore = FALSE; + bDisplayTime = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + fsm = FSM_FORMATION; +} + +void Football_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < FOOTBALL_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + if (!bPower){ + Football_ClearScreen(); + bInFrame = FALSE; + return; + } + + Platform_StartDraw(); + + // run the game + (fsmfcn[fsm])(); + + // update the display + if (bDisplayBlips){ + DrawBlips(); + } else { + EraseBlips(); + } + + if (bDisplayScore){ + Football_DrawScores(nHScore, nVScore); + } + + if (bDisplayYard){ + Football_DrawYard(TRANSLATE_YARD(nCurrentYardline)); + } else if (bDisplayTime){ + Football_DrawTime(fGameTime); + } + + if (bDisplayDown){ + int nYardsToGo = nCurrentYardline - nFirstDownYard; + if (nYardsToGo > ball.nYard){ + // don't show yards to go if more than distance to goal + Football_DrawDown(nDown, -1); + } else { + Football_DrawDown(nDown, nYardsToGo); + } + } + + if (!bDisplayDown && !bDisplayScore){ + Football_DrawScores(-1, -1); + } + + if (!bDisplayTime && !bDisplayYard){ + Football_DrawTime(-1); + } + + Platform_EndDraw(); + + bInFrame = FALSE; + +} + +void DrawBlips() +{ + int x, y, nBright; + static int nBlinkTimer = 0; + static BOOL bBlink = FALSE; + + for (int i=0; i= 4) && (!bGotFirstDown)){ + + // give the ball to the other team + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nFirstDownYard = ball.nYard - 10; + + Football_PlaySound(FOOTBALL_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + + } else { + Football_PlaySound(FOOTBALL_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + } + + return; + } + + + // move the defense randomly towards the ball + if (Platform_Random(100) < ((bPro2) ? 20 : 10)){ + int i = Platform_Random(NUM_DEFENSEPLAYERS); + if (player[i].nBright){ + // pick horizontal or vertical movement toward the ball + if (Platform_Random(2) == 0){ + if (player[i].nColumn < ball.nColumn){ + if (!ISDEFENSE(player[i].nColumn+1, player[i].nLane)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nColumn++; + } + } else if (player[i].nColumn > ball.nColumn){ + if (!ISDEFENSE(player[i].nColumn-1, player[i].nLane)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nColumn--; + } + } + } else { + if (player[i].nLane < ball.nLane){ + if (!ISDEFENSE(player[i].nColumn, player[i].nLane+1)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nLane++; + } + } else if (player[i].nLane > ball.nLane){ + if (!ISDEFENSE(player[i].nColumn, player[i].nLane-1)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nLane--; + } + } + } + } + } + + + // check for collisions again + if (ISDEFENSE(ball.nColumn, ball.nLane)){ + // tackled! + Football_ClearScreen(); + + int i = GETPLAYERAT(ball.nColumn, ball.nLane); + if (i != -1){ + UNMOVEPLAYER(player[i]); + SETPLAYERBRIGHTNESS(player[i], BLIP_DIMBLINK); + } + + if ((++nDown >= 4) && (!bGotFirstDown)){ + + // give the ball to the other team + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nFirstDownYard = ball.nYard - 10; + + Football_PlaySound(FOOTBALL_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + + } else { + Football_PlaySound(FOOTBALL_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + } + + return; + } + + + // count down the clock + if (Platform_IsNewSecond()){ + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime > 0.0){ + Football_PlaySound(FOOTBALL_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + } else { + // end of quarter! + fGameTime = 0.0; + } + } + } + +} + + +static void fsmPlayEnded() +{ + bDisplayTime = FALSE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + BOOL bEndOfQuarter = (fGameTime < 0.1) ? TRUE : FALSE; + + // check for game over + if (bEndOfQuarter && (nQuarter == 3)){ + fGameTime = 0.0; + bDisplayBlips = FALSE; + fsm = FSM_GAMEOVER; + return; + } + + // display '00' if clock ran out + if (bEndOfQuarter){ + fGameTime = 0.0; + bDisplayTime = TRUE; + bDisplayBlips = FALSE; + } + + if ((Football_GetInputSCORE(NULL) && !bEndOfQuarter) // end of quarter must press STATUS to set up next play + || (Football_GetInputSTATUS(NULL))){ + + Football_StopSound(); + + // if clock ran down in previous play + if (bEndOfQuarter){ + ++nQuarter; + if (nQuarter == 2){ + // halftime - force kickoff + // after halftime, visitor team gets possession + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + ball.nYard = 100 - 20; + nCurrentYardline = ball.nYard; + nFirstDownYard = nCurrentYardline - 10; + nDown = 0; + + fGameTime = 15.0; + fsm = FSM_FORMATION; + return; + } else { + fGameTime = 15.0; + } + } + + nCurrentYardline = ball.nYard; + + fsm = FSM_FORMATION; +// fsmFormation(); + return; + } + +} + + +static void fsmGameOver() +{ + bDisplayTime = TRUE; + bDisplayScore = TRUE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = FALSE; +} + + + + + diff --git a/source/game/Football.h b/source/game/Football.h new file mode 100644 index 0000000..077a296 --- /dev/null +++ b/source/game/Football.h @@ -0,0 +1,61 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __FOOTBALL_H__ +#define __FOOTBALL_H__ + +#include "Platform.h" +#include "Platform_Football.h" + + +#define FOOTBALL_BLIP_ROWS 3 +#define FOOTBALL_BLIP_COLUMNS 9 + +#define FOOTBALL_SOUND_TICK 0 +#define FOOTBALL_SOUND_ENDPLAY 1 +#define FOOTBALL_SOUND_ENDPOSSESSION 2 +#define FOOTBALL_SOUND_SCORE 3 + +void Football_Run(); +void Football_SetSkill(int i); +int Football_GetSkill(); +void Football_PowerOn(); +void Football_PowerOff(); +int Football_GetPower(); + + +#endif + diff --git a/source/game/Football2.c b/source/game/Football2.c new file mode 100644 index 0000000..0ae32ec --- /dev/null +++ b/source/game/Football2.c @@ -0,0 +1,1560 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "Football2.h" +#include "Games.h" + +// constants + +#define NUM_DEFENSEPLAYERS 6 +#define MAX_YARD 100 + +typedef int BLIP; + +static BLIP Blips[FOOTBALL2_BLIP_COLUMNS][FOOTBALL2_BLIP_ROWS]; + +// game variables +static BOOL bHomeTeam; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bPro2 = FALSE; +static BOOL bGotFirstDown; + +static BOOL bDisplayScore; +static BOOL bDisplayTime; +static BOOL bDisplayYard; +static BOOL bDisplayDown; +static BOOL bDisplayBlips; + +static int nHScore; +static int nVScore; +static float fGameTime; +static int nFirstDownYard; +static int nDown; +static int nQuarter; +static int nCurrentYardline; + +static int nPassingStart; + +static int nKickoffStart; +static int nKickoffDestination; + +static BOOL bCanKick; +static BOOL bPunting; +static BOOL bFieldGoalAttempt; + +typedef struct PLAYER { + int nYard; + int nColumn; + int nLane; + int nBright; + + int nColumnOld; + int nLaneOld; + int nYardOld; +}PLAYER; + +static PLAYER ball; +static PLAYER receiver; +static PLAYER player[NUM_DEFENSEPLAYERS]; + +// macros for dealing with the players + +#define TRANSLATE_COLUMN(x) \ + (!bHomeTeam ? x : (FOOTBALL2_BLIP_COLUMNS - 1) - x) + +#define UNTRANSLATE_COLUMN(x) \ + (bHomeTeam ? x : (FOOTBALL2_BLIP_COLUMNS - 1) - x) + +#define TRANSLATE_YARD(x) \ + (!bHomeTeam ? x : (MAX_YARD - x)) + +#define SETPLAYERBRIGHTNESS(p,b) { \ + p.nBright = b; \ +} + +#define NOTECURRENTPLAYERPOSITION(p) { \ + p.nColumnOld = p.nColumn; \ + p.nLaneOld = p.nLane; \ + p.nYardOld = p.nYard; \ +} + +#define SETPLAYER(p,a,x,y,b) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard = a; \ + p.nColumn = TRANSLATE_COLUMN(x); \ + p.nLane = y; \ + p.nBright = b; \ +} + +#define UNSETPLAYER(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard = -1; \ + p.nColumn = -1; \ + p.nLane = -1; \ + p.nBright = BLIP_OFF; \ +} + +#define MOVEPLAYERUP(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nLane--; \ +} +#define MOVEPLAYERDOWN(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nLane++; \ +} +#define MOVEPLAYERLEFT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn--; \ + if (p.nColumn < 0){ \ + p.nColumn = FOOTBALL2_BLIP_COLUMNS-1; \ + } \ + if (!bHomeTeam){ \ + p.nYard--; \ + } else { \ + p.nYard++; \ + } \ +} +#define MOVEPLAYERRIGHT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn++; \ + if (p.nColumn >= FOOTBALL2_BLIP_COLUMNS){ \ + p.nColumn = 0; \ + } \ + if (!bHomeTeam){ \ + p.nYard++; \ + } else { \ + p.nYard--; \ + } \ +} +#define MOVEPLAYERDOWNFIELD(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard--; \ + if (bHomeTeam){ \ + p.nColumn++; \ + if (p.nColumn >= FOOTBALL2_BLIP_COLUMNS){ \ + p.nColumn = 0; \ + } \ + } else { \ + p.nColumn--; \ + if (p.nColumn < 0){ \ + p.nColumn = FOOTBALL2_BLIP_COLUMNS-1; \ + } \ + } \ +} +#define MOVEPLAYERUPFIELD(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nYard++; \ + if (!bHomeTeam){ \ + p.nColumn++; \ + if (p.nColumn >= FOOTBALL2_BLIP_COLUMNS){ \ + p.nColumn = 0; \ + } \ + } else { \ + p.nColumn--; \ + if (p.nColumn < 0){ \ + p.nColumn = FOOTBALL2_BLIP_COLUMNS-1; \ + } \ + } \ +} + +static BOOL ISBALL(int x, int y); +static BOOL ISBALL(int x, int y) +{ + if ((ball.nColumn == x) + && (ball.nLane == y) + && (ball.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISRECEIVER(int x, int y); +static BOOL ISRECEIVER(int x, int y) +{ + if ((receiver.nColumn == x) + && (receiver.nLane == y) + && (receiver.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISDEFENSE(int x, int y); +static BOOL ISDEFENSE(int x, int y) +{ + for (int i=0; i FOOTBALL2_BLIP_COLUMNS-1) || (p.nColumn < 0)) + + + +// finite state machine stuff + +static void fsmKickoffWait(); +static void fsmKickoffCharge(); +static void fsmKickoffMidair(); +static void fsmKickoffRunbackWait(); +static void fsmKickoffRunback(); +static void fsmKickoffSafety(); +static void fsmFormation(); +static void fsmInPlay(); +static void fsmPassing(); +static void fsmSafety(); +static void fsmPlayEnded(); +static void fsmGameOver(); + +static enum FSM { + FSM_KICKOFFWAIT=0, + FSM_KICKOFFCHARGE, + FSM_KICKOFFMIDAIR, + FSM_KICKOFFRUNBACKWAIT, + FSM_KICKOFFRUNBACK, + FSM_KICKOFFSAFETY, + FSM_FORMATION, + FSM_INPLAY, + FSM_PASSING, + FSM_SAFETY, + FSM_PLAYENDED, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmKickoffWait, + fsmKickoffCharge, + fsmKickoffMidair, + fsmKickoffRunbackWait, + fsmKickoffRunback, + fsmKickoffSafety, + fsmFormation, + fsmInPlay, + fsmPassing, + fsmSafety, + fsmPlayEnded, + fsmGameOver +}; + + +// proto's +static void InitGame(); +static void DrawBlips(); +static void EraseBlips(); + + + +int Football2_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void Football2_PowerOn() +{ + if (!bPower) + { + InitGame(); + bPower = TRUE; + } +} + +void Football2_PowerOff() +{ + bPower = FALSE; + Football2_StopSound(); +} + +void Football2_SetSkill(int i){ + if (i == 0){ + bPro2 = FALSE; + } else { + bPro2 = TRUE; + } +} + +int Football2_GetSkill(){ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + + nHScore = 0; + nVScore = 0; + fGameTime = 15.0; + nDown = -1; + nQuarter = 0; + nCurrentYardline = 35; + + bDisplayScore = FALSE; + bDisplayTime = TRUE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + fsm = FSM_KICKOFFWAIT; +} + +void Football2_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < FOOTBALL2_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL2_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + if (!bPower){ + Football2_ClearScreen(); + bInFrame = FALSE; + return; + } + + Platform_StartDraw(); + + // run the game + (fsmfcn[fsm])(); + + // update the display + if (bDisplayBlips){ + DrawBlips(); + } else { + EraseBlips(); + } + + if (bDisplayScore){ + Football2_DrawScores(nHScore, nVScore); + } + + if (bDisplayYard){ + Football2_DrawYard(TRANSLATE_YARD(nCurrentYardline)); + } else if (bDisplayTime){ + Football2_DrawTime(fGameTime); + } + + if (bDisplayDown){ + Football2_DrawDown(nDown, nCurrentYardline - nFirstDownYard); + } + + if (!bDisplayDown && !bDisplayScore){ + Football2_DrawScores(-1, -1); + } + + if (!bDisplayTime && !bDisplayYard){ + Football2_DrawTime(-1); + } + + Platform_EndDraw(); + + bInFrame = FALSE; + +} + +void DrawBlips() +{ + int x, y, nBright; + static BOOL blink = FALSE; + + for (int i=0; i= nKickoffDestination){ + // back has landed + Football2_ClearScreen(); + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHT); + if (bPunting){ + + // put 2 receivers randomly on the screen + for (int n=0; n<2; n++){ + int i = Platform_Random(NUM_DEFENSEPLAYERS); + if (player[i].nBright == BLIP_OFF){ + int x, y; + do { + // find a random place on the screen + // don't land on top of anyone + x = Platform_Random(FOOTBALL2_BLIP_COLUMNS); + y = Platform_Random(FOOTBALL2_BLIP_ROWS); + } while (ISOCCUPIED(TRANSLATE_COLUMN(x), y)); + SETPLAYER(player[i], 0, x, y, BLIP_DIM); + } + } + + Football2_PlaySound(FOOTBALL2_SOUND_RUNBACK, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_KICKOFFRUNBACKWAIT; + + } else if (bFieldGoalAttempt){ + // field goal attempt failed + // put ball back to where it was kicked from + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + ball.nYard = 100 - nKickoffStart; + nCurrentYardline = ball.nYard; + nFirstDownYard = ball.nYard - 10; + + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + fsm = FSM_PLAYENDED; + } else { + Football2_PlaySound(FOOTBALL2_SOUND_RUNBACK, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_KICKOFFRUNBACKWAIT; + } + bPunting = FALSE; + bFieldGoalAttempt = FALSE; + return; + } else if (ball.nYard >= 100){ + + Football2_ClearScreen(); + + // ball landed in endzone + if (bFieldGoalAttempt){ + // successful + if (bHomeTeam){ + nVScore += 3; + } else { + nHScore += 3; + } + Football2_PlaySound(FOOTBALL2_SOUND_TOUCHDOWN, PLAYSOUNDFLAGS_PRIORITY); + ball.nYard = 35; + nCurrentYardline = ball.nYard; + nFirstDownYard = nCurrentYardline - 35; + bFieldGoalAttempt = FALSE; + fsm = FSM_KICKOFFWAIT; + } else if (bPunting){ + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + ball.nYard = MAX_YARD - 20; + nCurrentYardline = ball.nYard; + nFirstDownYard = nCurrentYardline - 10; + bPunting = FALSE; + fsm = FSM_PLAYENDED; + } else { + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + bPunting = FALSE; + fsm = FSM_KICKOFFSAFETY; + } + return; + } + } + i = !i; + + if (Platform_IsNewSecond() + && (fsm == FSM_KICKOFFMIDAIR)){ + Football2_PlaySound(FOOTBALL2_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + } +} + +static void fsmKickoffRunbackWait() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = FALSE; + + if (Football2_GetInputSCORE(NULL)){ + bDisplayScore = TRUE; + } else if (Football2_GetInputSTATUS(NULL)){ + bDisplayYard = TRUE; + } else { + bDisplayBlips = TRUE; + } + + if ((Football2_GetInputLEFT(NULL)) + || (Football2_GetInputUP(NULL)) + || (Football2_GetInputRIGHT(NULL)) + || (Football2_GetInputDOWN(NULL))){ + Platform_IsNewSecond(); + fsm = FSM_KICKOFFRUNBACK; + fsmKickoffRunback(); + return; + } +} + +static void fsmKickoffRunback() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + BOOL bChange; + if (Football2_GetInputLEFT(&bChange)) + { + if (bChange) + { + MOVEPLAYERLEFT(ball); + if (bHomeTeam && (ball.nColumn == (FOOTBALL2_BLIP_COLUMNS-1))) + { + MOVEPLAYERRIGHT(ball); + } + } + } + else if (Football2_GetInputRIGHT(&bChange)) + { + if (bChange) + { + MOVEPLAYERRIGHT(ball); + if (!bHomeTeam && ((ball.nColumn % FOOTBALL2_BLIP_COLUMNS) == 0)) + { + MOVEPLAYERLEFT(ball); + } + } + } + else if (Football2_GetInputUP(&bChange)) + { + if (bChange) + { + if (ball.nLane) + { + MOVEPLAYERUP(ball); + } + } + } + else if (Football2_GetInputDOWN(&bChange)) + { + if (bChange) + { + if (ball.nLane < 2) + { + MOVEPLAYERDOWN(ball); + } + } + } + + // check for touchdown + if (ball.nYard < 0){ + // touchdown!! + if (bHomeTeam){ + nHScore += 7; + } else { + nVScore += 7; + } + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_TOUCHDOWN, PLAYSOUNDFLAGS_PRIORITY); + Platform_IsNewSecond(); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nCurrentYardline = 35; + fsm = FSM_KICKOFFWAIT; + return; + } + + + // check for collisions + if (ISDEFENSE(ball.nColumn, ball.nLane)){ + // tackled! + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + + int i = GETPLAYERAT(ball.nColumn, ball.nLane); + if (i != -1){ + SETPLAYERBRIGHTNESS(player[i], BLIP_DIMBLINK); + } + + UNMOVEPLAYER(ball); + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + + nFirstDownYard = ball.nYard - 10; + + Platform_IsNewSecond(); + fsm = FSM_PLAYENDED; + return; + } + + + // move the defense randomly towards the ball + if (Platform_Random(100) < ((bPro2) ? 25 : 15)){ + int i = Platform_Random(NUM_DEFENSEPLAYERS); + if (player[i].nBright){ + // pick horizontal or vertical movement toward the ball + if (Platform_Random(2) == 0){ + if (player[i].nColumn < ball.nColumn){ + if (!ISDEFENSE(player[i].nColumn+1, player[i].nLane)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nColumn++; + } + } else if (player[i].nColumn > ball.nColumn){ + if (!ISDEFENSE(player[i].nColumn-1, player[i].nLane)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nColumn--; + } + } + } else { + if (player[i].nLane < ball.nLane){ + if (!ISDEFENSE(player[i].nColumn, player[i].nLane+1)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nLane++; + } + } else if (player[i].nLane > ball.nLane){ + if (!ISDEFENSE(player[i].nColumn, player[i].nLane-1)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nLane--; + } + } + } + } + } + + // randomly add defense players + if (Platform_Random(10) < 3){ + int i = Platform_Random(NUM_DEFENSEPLAYERS); + if (player[i].nBright == BLIP_OFF){ + int x, y; + do { + // find a random place on the screen + // don't land on top of anyone + x = Platform_Random(FOOTBALL2_BLIP_COLUMNS); + y = Platform_Random(FOOTBALL2_BLIP_ROWS); + } while (ISOCCUPIED(TRANSLATE_COLUMN(x), y)); + SETPLAYER(player[i], 0, x, y, BLIP_DIM); + } + } + + + // check for collisions again + if (ISDEFENSE(ball.nColumn, ball.nLane)){ + // tackled! + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + + int i = GETPLAYERAT(ball.nColumn, ball.nLane); + if (i != -1){ + UNMOVEPLAYER(player[i]); + SETPLAYERBRIGHTNESS(player[i], BLIP_DIMBLINK); + } + + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + + nFirstDownYard = ball.nYard - 10; + + Platform_IsNewSecond(); + fsm = FSM_PLAYENDED; + return; + } + + + // count down the clock + if (Platform_IsNewSecond()){ + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime > 0.0){ + Football2_PlaySound(FOOTBALL2_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + } else { + // end of quarter! + fGameTime = 0.0; + Football2_PlaySound(FOOTBALL2_SOUND_ENDQUARTER, PLAYSOUNDFLAGS_PRIORITY); + } + } + } + +} + +static void fsmKickoffSafety() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + if ((Football2_GetInputLEFT(NULL)) + || (Football2_GetInputUP(NULL)) + || (Football2_GetInputRIGHT(NULL)) + || (Football2_GetInputDOWN(NULL)) + || (Football2_GetInputSCORE(NULL)) + || (Football2_GetInputSTATUS(NULL))){ + nCurrentYardline = MAX_YARD - 20; + nFirstDownYard = nCurrentYardline - 10; + fsmFormation(); + fsm = FSM_FORMATION; + return; + } +} + + +static void fsmFormation() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = FALSE; + + if (Football2_GetInputSCORE(NULL)){ + bDisplayScore = TRUE; + } else if (Football2_GetInputSTATUS(NULL)){ + bDisplayYard = TRUE; + bDisplayDown = TRUE; + } else { + bDisplayBlips = TRUE; + } + + if (bGotFirstDown){ + nFirstDownYard = nCurrentYardline - 10; + nDown = 0; + bGotFirstDown = FALSE; + } + + // set up the players in formation + + UNSETPLAYER(receiver); + SETPLAYER(ball, nCurrentYardline+1, 7, 1, BLIP_BRIGHT); + + SETPLAYER(player[0], nCurrentYardline-6, 0, 2, BLIP_DIM); + SETPLAYER(player[1], nCurrentYardline-4, 2, 0, BLIP_DIM); + SETPLAYER(player[2], nCurrentYardline-2, 4, 1, BLIP_DIM); + SETPLAYER(player[3], nCurrentYardline-0, 6, 0, BLIP_DIM); + SETPLAYER(player[4], nCurrentYardline-0, 6, 1, BLIP_DIM); + SETPLAYER(player[5], nCurrentYardline-0, 6, 2, BLIP_DIM); + + // wait for player to move, then start play + BOOL bChange; + if (Football2_GetInputPASS(&bChange)) + { + if (bChange) + { + // pass + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + nPassingStart = ball.nYard; + fsm = FSM_PASSING; + fsmPassing(); + return; + } + } + else if (Football2_GetInputKICK(&bChange)) + { + if (bChange) + { + // punt + + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nCurrentYardline = ball.nYard; + + UNSETPLAYER(player[0]); + UNSETPLAYER(player[1]); + UNSETPLAYER(player[2]); + UNSETPLAYER(player[3]); + UNSETPLAYER(player[4]); + UNSETPLAYER(player[5]); + + // calculate where ball will land + nKickoffDestination = ball.nYard + (Platform_Random(50) + 10); + + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + Platform_IsNewSecond(); + bPunting = TRUE; + fsm = FSM_KICKOFFMIDAIR; + return; + } + } + else if (Football2_TestForMovement()) + { + bCanKick = TRUE; + + Platform_IsNewSecond(); + if (Platform_Random(2)){ + SETPLAYER(receiver, nCurrentYardline-1, 5, 0, BLIP_DIMBLINK); + } else { + SETPLAYER(receiver, nCurrentYardline-1, 5, 2, BLIP_DIMBLINK); + } + + fsm = FSM_INPLAY; + fsmInPlay(); + return; + } +} + +static void fsmInPlay() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + BOOL bChange; + if (Football2_GetInputLEFT(&bChange)) + { + if (bChange) + { + MOVEPLAYERLEFT(ball); + if (bHomeTeam && (ball.nColumn == (FOOTBALL2_BLIP_COLUMNS-1))) + { + MOVEPLAYERRIGHT(ball); + } + } + } + else if (Football2_GetInputRIGHT(&bChange)) + { + if (bChange) + { + MOVEPLAYERRIGHT(ball); + if (!bHomeTeam && ((ball.nColumn % FOOTBALL2_BLIP_COLUMNS) == 0)) + { + MOVEPLAYERLEFT(ball); + } + } + } + else if (Football2_GetInputUP(&bChange)) + { + if (bChange) + { + if (ball.nLane) + { + bCanKick = FALSE; + MOVEPLAYERUP(ball); + } + } + } + else if (Football2_GetInputDOWN(&bChange)) + { + if (bChange) + { + if (ball.nLane < 2) + { + bCanKick = FALSE; + MOVEPLAYERDOWN(ball); + } + } + } + + if (Football2_GetInputPASS(NULL) && (ball.nYard >= nCurrentYardline)){ + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + nPassingStart = UNTRANSLATE_COLUMN(ball.nColumn); + fsm = FSM_PASSING; + fsmPassing(); + return; + } + if (Football2_GetInputKICK(NULL) && bCanKick){ + + // field goal attempt! + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nKickoffStart = nCurrentYardline; + nCurrentYardline = ball.nYard; + + UNSETPLAYER(player[0]); + UNSETPLAYER(player[1]); + UNSETPLAYER(player[2]); + UNSETPLAYER(player[3]); + UNSETPLAYER(player[4]); + UNSETPLAYER(player[5]); + UNSETPLAYER(receiver); + + // calculate where ball will land + nKickoffDestination = ball.nYard + (Platform_Random(30) + 10); + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + Platform_IsNewSecond(); + bFieldGoalAttempt = TRUE; + fsm = FSM_KICKOFFMIDAIR; + + return; + } + + int nYardsToGo = ball.nYard - nFirstDownYard; + + // 1st down + if (nYardsToGo <= 0){ + if (!bGotFirstDown){ + Football2_PlaySound(FOOTBALL2_SOUND_FIRSTDOWN, PLAYSOUNDFLAGS_PRIORITY); + bGotFirstDown = TRUE; + } + } else { + bGotFirstDown = FALSE; + } + + + // get rid of the receiver once we've + // passed the line of scrimmage + if (ball.nYard < nCurrentYardline){ + UNSETPLAYER(receiver); + } + + // check for touchdown + if (ball.nYard < 0){ + // touchdown!! + if (bHomeTeam){ + nHScore += 7; + } else { + nVScore += 7; + } + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_TOUCHDOWN, PLAYSOUNDFLAGS_PRIORITY); + Platform_IsNewSecond(); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nCurrentYardline = 35; + fsm = FSM_KICKOFFWAIT; + return; + } + + // check for collisions + if (ISDEFENSE(ball.nColumn, ball.nLane)){ + // tackled! + Football2_ClearScreen(); + + int i = GETPLAYERAT(ball.nColumn, ball.nLane); + if (i != -1){ + SETPLAYERBRIGHTNESS(player[i], BLIP_DIMBLINK); + } + + UNMOVEPLAYER(ball); + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + UNSETPLAYER(receiver); + + if (ball.nYard > 100){ + + // safety + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_SAFETY, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_SAFETY; + return; + + } else if ((++nDown >= 4) && (!bGotFirstDown)){ + + // give the ball to the other team + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nFirstDownYard = ball.nYard - 10; + + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + + } else { + Football2_PlaySound(FOOTBALL2_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + } + + return; + } + + + // move the defense randomly towards the ball + if (Platform_Random(100) < ((bPro2) ? 25 : 15)){ + int i = Platform_Random(NUM_DEFENSEPLAYERS); + if (player[i].nBright){ + // pick horizontal or vertical movement toward the ball + if (Platform_Random(2) == 0){ + if (player[i].nColumn < ball.nColumn){ + if (!ISDEFENSE(player[i].nColumn+1, player[i].nLane) + && !ISRECEIVER(player[i].nColumn+1, player[i].nLane)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nColumn++; + } + } else if (player[i].nColumn > ball.nColumn){ + if (!ISDEFENSE(player[i].nColumn-1, player[i].nLane) + && !ISRECEIVER(player[i].nColumn-1, player[i].nLane)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nColumn--; + } + } + } else { + if (player[i].nLane < ball.nLane){ + if (!ISDEFENSE(player[i].nColumn, player[i].nLane+1) + && !ISRECEIVER(player[i].nColumn, player[i].nLane+1)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nLane++; + } + } else if (player[i].nLane > ball.nLane){ + if (!ISDEFENSE(player[i].nColumn, player[i].nLane-1) + && !ISRECEIVER(player[i].nColumn, player[i].nLane-1)){ + NOTECURRENTPLAYERPOSITION(player[i]); + player[i].nLane--; + } + } + } + } + } + + + // move the receiver randomly + if (Platform_Random(100) < ((bPro2) ? 15 : 5)){ + if (receiver.nBright){ + // pick horizontal or vertical movement toward the ball + if (Platform_Random(4) == 0){ + if (receiver.nLane < ball.nLane){ + if (!ISOCCUPIED(receiver.nColumn, receiver.nLane+1)){ + NOTECURRENTPLAYERPOSITION(receiver); + receiver.nLane++; + } + } else if (receiver.nLane > ball.nLane){ + if (!ISOCCUPIED(receiver.nColumn, receiver.nLane-1)){ + NOTECURRENTPLAYERPOSITION(receiver); + receiver.nLane--; + } + } + } else { + if (Platform_Random(3) == 0){ + int dir = (bHomeTeam) ? 1 : -1; + if (!ISOCCUPIED(receiver.nColumn + dir, receiver.nLane)){ + NOTECURRENTPLAYERPOSITION(receiver); + receiver.nColumn += dir; + if (ISPLAYEROFFSCREEN(receiver)){ + UNMOVEPLAYER(receiver); + } + } + } + } + + } + } + + + // check for collisions again + if (ISDEFENSE(ball.nColumn, ball.nLane)){ + // tackled! + Football2_ClearScreen(); + + int i = GETPLAYERAT(ball.nColumn, ball.nLane); + if (i != -1){ + UNMOVEPLAYER(player[i]); + SETPLAYERBRIGHTNESS(player[i], BLIP_DIMBLINK); + } + + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHTBLINK); + UNSETPLAYER(receiver); + + if (ball.nYard > 100){ + + // safety + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_SAFETY, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_SAFETY; + return; + + } else if ((++nDown >= 4) && (!bGotFirstDown)){ + + // give the ball to the other team + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nFirstDownYard = ball.nYard - 10; + + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + } else { + Football2_PlaySound(FOOTBALL2_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + fsm = FSM_PLAYENDED; + return; + } + + return; + } + + + // count down the clock + if (Platform_IsNewSecond()){ + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime > 0.0){ + Football2_PlaySound(FOOTBALL2_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + } else { + // end of quarter! + fGameTime = 0.0; + Football2_PlaySound(FOOTBALL2_SOUND_ENDQUARTER, PLAYSOUNDFLAGS_PRIORITY); + } + } + } +} + +static void fsmPassing() +{ +static int i = 0; +BOOL bIntercepted = FALSE; + + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + if (i==0){ + + MOVEPLAYERDOWNFIELD(ball); + + if ((ball.nColumn == receiver.nColumn) + && (ball.nLane == receiver.nLane)){ + + // completed pass + UNSETPLAYER(receiver); + SETPLAYERBRIGHTNESS(ball, BLIP_BRIGHT); + fsm = FSM_INPLAY; + + } else if ((ball.nColumn == 0) + || (ball.nColumn == FOOTBALL2_BLIP_COLUMNS-1)){ + + // incomplete pass + Football2_ClearScreen(); + ++nDown; + ball.nYard = nCurrentYardline; + if ((++nDown >= 4) && (!bGotFirstDown)){ + + // give the ball to the other team + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nFirstDownYard = ball.nYard - 10; + + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + + } else { + Football2_PlaySound(FOOTBALL2_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + } + + Platform_IsNewSecond(); + fsm = FSM_PLAYENDED; + + } else if (ISDEFENSE(ball.nColumn, ball.nLane)){ + + // ** The passed ball can only pass over defense players + // on the offense side of the line of scrimmage. All others + // will intercept the ball (per instruction manual) + + if (UNTRANSLATE_COLUMN(ball.nColumn) >= 3) + { + // intercepted! + Football2_ClearScreen(); + Football2_PlaySound(FOOTBALL2_SOUND_ENDPOSSESSION, PLAYSOUNDFLAGS_PRIORITY); + + UNSETPLAYER(receiver); + + int n = GETPLAYERAT(ball.nColumn, ball.nLane); + if (n != -1){ + SETPLAYERBRIGHTNESS(player[n], BLIP_DIMBLINK); + } + + // unmove the ball + UNMOVEPLAYER(ball); + + // give the ball to the other team + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nDown = 0; + ball.nYard = MAX_YARD - ball.nYard; + nFirstDownYard = ball.nYard - 10; + + Platform_IsNewSecond(); + fsm = FSM_PLAYENDED; + } + } + } + + if ((++i == 5) || (fsm != FSM_PASSING)){ + i = 0; + } + + // count down the clock + if (Platform_IsNewSecond()){ + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime > 0.0){ + Football2_PlaySound(FOOTBALL2_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + } else { + // end of quarter! + fGameTime = 0.0; + Football2_PlaySound(FOOTBALL2_SOUND_ENDQUARTER, PLAYSOUNDFLAGS_PRIORITY); + } + } + } +} + +static void fsmSafety() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + UNSETPLAYER(receiver); + + // check for game over + if ((fGameTime <= 0.0) && (nQuarter == 3)){ + // add the 2 points for the safety + if (bHomeTeam){ + nVScore += 2; + } else { + nHScore += 2; + } + + fsm = FSM_GAMEOVER; + return; + } + + if (Football2_GetInputSCORE(NULL) || Football2_GetInputSTATUS(NULL)){ + // if clock ran down in previous play + if (fGameTime < 0.1){ + ++nQuarter; + if (nQuarter == 2){ + // halftime - force kickoff + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + ball.nYard = 35; + nCurrentYardline = ball.nYard; + nFirstDownYard = nCurrentYardline - 35; + + // add the 2 points for the safety + if (bHomeTeam){ + nVScore += 2; + } else { + nHScore += 2; + } + + fGameTime = 15.0; + fsm = FSM_KICKOFFWAIT; + return; + } else { + fGameTime = 15.0; + } + } + + // add 2 points and set up kickoff from 20 yardline + if (bHomeTeam){ + nVScore += 2; + } else { + nHScore += 2; + } + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + ball.nYard = 20; + nCurrentYardline = ball.nYard; + nFirstDownYard = nCurrentYardline - 10; + + fsm = FSM_KICKOFFWAIT; + fsmKickoffWait(); + return; + } + +} + +static void fsmPlayEnded() +{ + bDisplayTime = TRUE; + bDisplayScore = FALSE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = TRUE; + + // check for game over + if ((fGameTime <= 0.0) && (nQuarter == 3)){ + fsm = FSM_GAMEOVER; + return; + } + + if ((Football2_GetInputSCORE(NULL)) + || (Football2_GetInputSTATUS(NULL))){ + // if clock ran down in previous play + if (fGameTime < 0.1){ + ++nQuarter; + if (nQuarter == 2){ + // halftime - force kickoff + // after halftime, home team gets possession + bHomeTeam = TRUE; + PlatformSetInput(bHomeTeam); + ball.nYard = 35; + nCurrentYardline = ball.nYard; + nFirstDownYard = nCurrentYardline - 10; + + fGameTime = 15.0; + fsm = FSM_KICKOFFWAIT; + return; + } else { + fGameTime = 15.0; + } + } + + nCurrentYardline = ball.nYard; + + fsm = FSM_FORMATION; + fsmFormation(); + return; + } + +} + +static void fsmGameOver() +{ + bDisplayTime = TRUE; + bDisplayScore = TRUE; + bDisplayYard = FALSE; + bDisplayDown = FALSE; + bDisplayBlips = FALSE; + +} + + + + + diff --git a/source/game/Football2.h b/source/game/Football2.h new file mode 100644 index 0000000..aea8d10 --- /dev/null +++ b/source/game/Football2.h @@ -0,0 +1,67 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __FOOTBALL2_H__ +#define __FOOTBALL2_H__ + + +#include "Platform.h" +#include "Platform_Football2.h" + + +#define FOOTBALL2_BLIP_ROWS 3 +#define FOOTBALL2_BLIP_COLUMNS 10 + +#define FOOTBALL2_SOUND_CHARGESTART 0 +#define FOOTBALL2_SOUND_CHARGE 1 +#define FOOTBALL2_SOUND_TICK 2 +#define FOOTBALL2_SOUND_RUNBACK 3 +#define FOOTBALL2_SOUND_FIRSTDOWN 4 +#define FOOTBALL2_SOUND_ENDPLAY 5 +#define FOOTBALL2_SOUND_ENDPOSSESSION 6 +#define FOOTBALL2_SOUND_ENDQUARTER 7 +#define FOOTBALL2_SOUND_TOUCHDOWN 8 +#define FOOTBALL2_SOUND_SAFETY 9 + +void Football2_Run(); +void Football2_SetSkill(int i); +int Football2_GetSkill(); +void Football2_PowerOn(); +void Football2_PowerOff(); +int Football2_GetPower(); + + +#endif diff --git a/source/game/Hockey.c b/source/game/Hockey.c new file mode 100644 index 0000000..b2f3a01 --- /dev/null +++ b/source/game/Hockey.c @@ -0,0 +1,1493 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "Hockey.h" +#include "Games.h" + + +// constants + +#define NUM_DEFENSEPLAYERS 4 + +#define TIME_TICKTIMERPRO1 7 +#define TIME_TICKTIMERPRO2 4 +#define TIME_STATSDISPLAY 5 +#define TIME_PUCKMOVE 3 +#define TIME_PENALTY 20 // (2 simulated minutes) + +typedef int BLIP; + +static BLIP Blips[HOCKEY_BLIP_COLUMNS][HOCKEY_BLIP_ROWS]; + +// game variables +static BOOL bGameOver; +static BOOL bHomeTeam; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bPro2 = FALSE; + +static int nHScore; +static int nVScore; +static float fGameTime; +static int nPeriod; +static int nTimerTickTimer; + +static BOOL bShoot; +static int nPuckDirectionX; +static int nPuckDirectionY; +static int nTimerPuckMove; + +static BOOL bBumped; +static int nPenalty; +static int nPenaltyTimer; + +static BOOL bDeflect; +static BOOL bSteal; + +static int nStatsIndex; +static int nTimerStatsDisplay; + +static int nBehindGoalDirX = 0; + +static int nDeflectPointX = 0; +static int nDeflectPointY = 0; + +typedef struct PLAYER { + int nColumn; + int nRow; + int nBright; + int nColumnOld; + int nRowOld; +}PLAYER; + +static PLAYER puck; +static PLAYER player; +static PLAYER defense[NUM_DEFENSEPLAYERS]; + +// macros for dealing with the players + +#define SETPLAYERBRIGHTNESS(p,b) { \ + p.nBright = b; \ +} + +#define NOTECURRENTPLAYERPOSITION(p) { \ + p.nColumnOld = p.nColumn; \ + p.nRowOld = p.nRow; \ +} + +#define SETPLAYER(p,x,y,b) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn = x; \ + p.nRow = y; \ + p.nBright = b; \ +} + +#define UNSETPLAYER(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn = -1; \ + p.nRow = -1; \ + p.nBright = BLIP_OFF; \ +} + +#define MOVEPLAYERUP(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nRow--; \ +} +#define MOVEPLAYERDOWN(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nRow++; \ +} +#define MOVEPLAYERLEFT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn--; \ +} +#define MOVEPLAYERRIGHT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn++; \ +} + +static BOOL ISPUCK(int x, int y); +static BOOL ISPUCK(int x, int y) +{ + if ((puck.nColumn == x) + && (puck.nRow == y) + && (puck.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISPLAYER(int x, int y); +static BOOL ISPLAYER(int x, int y) +{ + if ((player.nColumn == x) + && (player.nRow == y) + && (player.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISDEFENSE(int x, int y); +static BOOL ISDEFENSE(int x, int y) +{ + for (int i=0; i HOCKEY_BLIP_COLUMNS-1) \ + || (p.nColumn < 0) \ + || (p.nRow > HOCKEY_BLIP_ROWS-1) \ + || (p.nRow < 0)) + + +#define ISPLAYERENABLED(p) \ + (p.nBright) + + +// finite state machine stuff + +static void fsmPlayStartWait(); +static void fsmShowStats(); +static void fsmInPlay(); +static void fsmGoal(); +static void fsmGameOver(); + + +static enum FSM { + FSM_PLAYSTARTWAIT=0, + FSM_SHOWSTATS, + FSM_INPLAY, + FSM_GOAL, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmPlayStartWait, + fsmShowStats, + fsmInPlay, + fsmGoal, + fsmGameOver +}; + + +// proto's +static void InitGame(); +static void DrawBlips(); +static void EraseBlips(); +static BOOL PenaltyTest(int x, int y); + + +BOOL Hockey_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void Hockey_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void Hockey_PowerOff() +{ + bPower = FALSE; + Hockey_StopSound(); +} + +void Hockey_SetSkill(int i){ + if (i == 0){ + bPro2 = FALSE; + } else { + bPro2 = TRUE; + } +} + +int Hockey_GetSkill(){ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + + nHScore = 0; + nVScore = 0; + fGameTime = (float)20.9; + nPeriod = 0; + bGameOver = FALSE; + nBehindGoalDirX = 0; + bBumped = FALSE; + nPenalty = 0; + nPenaltyTimer = 0; + bDeflect = FALSE; + bSteal = FALSE; + + // show stats when power is switched on + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + fsmShowStats(); +} + +void Hockey_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < HOCKEY_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEY_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + if (!bPower){ + Hockey_ClearScreen(); + bInFrame = FALSE; + return; + } + + Platform_StartDraw(); + + (fsmfcn[fsm])(); + + DrawBlips(); + + Platform_EndDraw(); + + bInFrame = FALSE; + +} + +void DrawBlips() +{ + int x, y, nBright; + static BOOL bBlink = FALSE; + + if(fsm != FSM_GOAL) { + for (int i=0; i 0) + { + // handle special behavior behind the goal + if ((player.nRow == 1) && (player.nColumn == 1)) + { + if (PenaltyTest(0, 2)) + { + return; + } + else if (!ISOCCUPIED(0, 2)) + { + SETPLAYER(player, 0, 2, player.nBright); + } + } + else if ((player.nRow == 0) && (player.nColumn == 2)) + { + if (PenaltyTest(1, 1)) + { + return; + } + else if (!ISOCCUPIED(1, 1)) + { + SETPLAYER(player, 1, 1, player.nBright); + } + } + else + { + if (PenaltyTest(player.nColumn-1, player.nRow)) + { + return; + } + else if (!ISOCCUPIED(player.nColumn-1, player.nRow)) + { + MOVEPLAYERLEFT(player); + } + } + } + + } + } + else if (Hockey_GetInputRIGHT(&bChange)) + { + if (bChange) + { + if (player.nColumn < (HOCKEY_BLIP_COLUMNS-1)) + { + // handle special behavior behind the goal + if ((player.nRow == 1) && (player.nColumn == 3)) + { + if (PenaltyTest(4, 2)) + { + return; + } + else if (!ISOCCUPIED(4, 2)) + { + SETPLAYER(player, 4, 2, player.nBright); + } + } + else if ((player.nRow == 0) && (player.nColumn == 2)) + { + if (PenaltyTest(3, 1)) + { + return; + } + else if (!ISOCCUPIED(3, 1)) + { + SETPLAYER(player, 3, 1, player.nBright); + } + } + else + { + if (PenaltyTest(player.nColumn+1, player.nRow)) + { + return; + } + else if (!ISOCCUPIED(player.nColumn+1, player.nRow)) + { + MOVEPLAYERRIGHT(player); + } + } + } + } + } + else if (Hockey_GetInputUP(&bChange)) + { + if (bChange) + { + if (player.nRow > 2) + { + if (PenaltyTest(player.nColumn, player.nRow-1)) + { + return; + } + else if (!ISOCCUPIED(player.nColumn, player.nRow-1)) + { + MOVEPLAYERUP(player); + } + } + + // handle special behavior behind the goal + else if (player.nRow == 1) + { + if ((player.nColumn == 3) || (player.nColumn == 1)) + { + if (PenaltyTest(2, 0)) + { + return; + } + else if (!ISOCCUPIED(2, 0)) + { + SETPLAYER(player, 2, 0, player.nBright); + } + } + } + else if (player.nRow == 2) + { + switch(player.nColumn) + { + case 0: + case 1: + if (PenaltyTest(1, 1)) + { + return; + } + else if (!ISOCCUPIED(1, 1)) + { + SETPLAYER(player, 1, 1, player.nBright); + } + break; + case 2: + // the goal - can't go there + break; + case 3: + case 4: + if (PenaltyTest(3, 1)) + { + return; + } + else if (!ISOCCUPIED(3, 1)) + { + SETPLAYER(player, 3, 1, player.nBright); + } + break; + } + } + } + } + else if (Hockey_GetInputDOWN(&bChange)) + { + if (bChange) + { + if (player.nRow < (HOCKEY_BLIP_ROWS-1)) + { + if (PenaltyTest(player.nColumn, player.nRow+1)) + { + return; + } + else if (!ISOCCUPIED(player.nColumn, player.nRow+1)) + { + MOVEPLAYERDOWN(player); + } + } + + } + } + + if (Hockey_GetInputTHROW(&bChange)) + { + if (bChange) + { + if (!ISPLAYERENABLED(puck)) + { + // shoot! + bShoot = TRUE; + nTimerPuckMove = TIME_PUCKMOVE; + SETPLAYERBRIGHTNESS(player, BLIP_DIMBLINK); + SETPLAYER(puck, player.nColumn, player.nRow, BLIP_BRIGHT); + + if (player.nRow < 2) + { + nPuckDirectionX = 0; + nPuckDirectionY = 0; + + if (player.nColumn < 2) + { + nBehindGoalDirX = 1; + } + else if (player.nColumn > 2) + { + nBehindGoalDirX = -1; + } + else + { + nBehindGoalDirX = Platform_Random(2) ? 1 : -1; + } + } + else + { + nPuckDirectionY = -1; + nBehindGoalDirX = 0; + + if (player.nColumn < 2) + { + nPuckDirectionX = 1; + } + else if (player.nColumn > 2) + { + nPuckDirectionX = -1; + } + else + { + nPuckDirectionX = 0; + } + } + + } + } + } + + // let the defenders try to pokecheck + // it's easier to check all 4 positions around the player than + // to check each defender separately + BOOL bPoked = FALSE; + if (!ISPLAYERENABLED(puck)) + { + if (player.nRow < 2) + { + // handle behind the goal + if ((((player.nColumn == 2) || (player.nRow == 0)) && ISDEFENSE(1, 1)) + || (((player.nColumn == 2) || (player.nRow == 0)) && ISDEFENSE(3, 1)) + || (((player.nColumn == 1) || (player.nRow == 1)) && ISDEFENSE(2, 0)) + || (((player.nColumn == 3) || (player.nRow == 1)) && ISDEFENSE(2, 1)) + || (((player.nColumn == 1) || (player.nRow == 1)) && ISDEFENSE(1, 2)) + || (((player.nColumn == 3) || (player.nRow == 1)) && ISDEFENSE(3, 2)) + || (((player.nColumn == 1) || (player.nRow == 1)) && ISDEFENSE(0, 2)) // not sure about this + || (((player.nColumn == 3) || (player.nRow == 1)) && ISDEFENSE(4, 2))) // not sure about this + { + if (Platform_Random(bPro2 ? 40 : 50) == 0) + { + bPoked = TRUE; + } + } + } + else + { + if ((player.nColumn > 0) && ISDEFENSE(player.nColumn-1, player.nRow)) + { + // left + if (Platform_Random(bPro2 ? 40 : 50) == 0) + { + bPoked = TRUE; + } + } + if ((player.nColumn < (HOCKEY_BLIP_COLUMNS-1)) && ISDEFENSE(player.nColumn+1, player.nRow)) + { + // right + if (Platform_Random(bPro2 ? 40 : 50) == 0) + { + bPoked = TRUE; + } + } + if ((player.nRow > 0) && ISDEFENSE(player.nColumn, player.nRow+1)) + { + // above + if (Platform_Random(bPro2 ? 40 : 50) == 0) + { + bPoked = TRUE; + } + } + if ((player.nRow < (HOCKEY_BLIP_ROWS-1)) && ISDEFENSE(player.nColumn, player.nRow-1)) + { + // below + if (Platform_Random(bPro2 ? 40 : 50) == 0) + { + bPoked = TRUE; + } + } + } + } + + if (bPoked) + { + Hockey_PlaySound(HOCKEY_SOUND_POKE, PLAYSOUNDFLAGS_PRIORITY); + + bShoot = TRUE; + nTimerPuckMove = TIME_PUCKMOVE; + SETPLAYERBRIGHTNESS(player, BLIP_DIMBLINK); + SETPLAYER(puck, player.nColumn, player.nRow, BLIP_BRIGHT); + + if (player.nRow < 2) + { + nPuckDirectionX = 0; + nPuckDirectionY = 0; + + if (player.nColumn < 2) + { + nBehindGoalDirX = 1; + } + else if (player.nColumn > 2) + { + nBehindGoalDirX = -1; + } + else + { + nBehindGoalDirX = Platform_Random(2) ? 1 : -1; + } + } + else + { + do + { + if (player.nColumn == 0) + { + nPuckDirectionX = Platform_Random(2); + } + else if (player.nColumn == (HOCKEY_BLIP_COLUMNS-1)) + { + nPuckDirectionX = -(Platform_Random(2)); + } + else + { + nPuckDirectionX = Platform_Random(3) - 1; + } + + if (player.nRow == 0) + { + nPuckDirectionY = Platform_Random(2); + } + else if (player.nRow == (HOCKEY_BLIP_ROWS-1)) + { + nPuckDirectionY = -(Platform_Random(2)); + } + else + { + nPuckDirectionY = Platform_Random(3) - 1; + } + } while((nPuckDirectionX == 0) && (nPuckDirectionY == 0)); + + nBehindGoalDirX = 0; + } + } + + + // establish a target for the defense + PLAYER *targetP = ISPLAYERENABLED(puck) ? &puck : &player; + + // move the goalie + { + if (Platform_Random(bPro2 ? 3 : 6) == 0) + { + if ((targetP->nColumn < defense[0].nColumn) + && (defense[0].nColumn > 1)) + { + if (!ISOCCUPIED(defense[0].nColumn-1, defense[0].nRow)) + { + defense[0].nColumn--; + } + } + else if ((targetP->nColumn > defense[0].nColumn) + && (defense[0].nColumn < 3)) + { + if (!ISOCCUPIED(defense[0].nColumn+1, defense[0].nRow)) + { + defense[0].nColumn++; + } + } + } + } + + // move the other defenders toward the target + { + if (Platform_Random(bPro2 ? 5 : 10) == 0) + { + // pick a random defender + static int nDefenderLast = -1; + int nDefender = nPenalty ? (Platform_Random(2) + 1) : (Platform_Random(3) + 1); + + if (nDefender != nDefenderLast) + { + nDefenderLast = nDefender; + + PLAYER *pDefender = &defense[nDefender]; + + int dx = pDefender->nColumn; + int dy = pDefender->nRow; + + // randomly move the defender towards the target + if (Platform_Random(2)) + { + if (dx < targetP->nColumn) + { + ++dx; + } + else if (dx > targetP->nColumn) + { + --dx; + } + } + else + { + if (dy < targetP->nRow) + { + ++dy; + } + else if (dy > targetP->nRow) + { + --dy; + } + } + + // occasionally randomly offset the defender's position + if (Platform_Random(5) == 0) + { + if (Platform_Random(2)) + { + dx += (Platform_Random(2)) ? 1 : -1; + } + else + { + dy += (Platform_Random(2)) ? 1 : -1; + } + } + + // need to allow defenders to move around behind goal, etc + if ((dx == 2) && (dy == 1)) + { + if ((pDefender->nColumn == 1) && (pDefender->nRow == 1)) + { + dx = 2; + dy = 0; + } + else if ((pDefender->nColumn == 2) && (pDefender->nRow == 0)) + { + dx = 2; + dy = 0; + } + else if ((pDefender->nColumn == 3) && (pDefender->nRow == 1)) + { + dx = 2; + dy = 0; + } + } + else if ((dx == 1) && (dy == 0)) + { + dx = 1; + dy = 1; + } + else if ((dx == 3) && (dy == 0)) + { + dx = 3; + dy = 1; + } + else if ((dx == 0) && (dy == 1)) + { + dx = 0; + dy = 2; + } + else if ((dx == 4) && (dy == 1)) + { + dx = 4; + dy = 2; + } + + // make sure the defender does not step on anybody, + // and keep him confined to the proper area + if (!ISOCCUPIED(dx, dy) + && (dx >= 0) + && (dx <= (HOCKEY_BLIP_COLUMNS - 1)) + && (dy >= 0) + && (dy <= (HOCKEY_BLIP_ROWS - 1))) + { + SETPLAYER((*pDefender), dx, dy, BLIP_DIM); + } + + } + } + } + + // move the puck + if (ISPLAYERENABLED(puck)) + { + // the puck hit a defender last frame - do something + if (ISDEFENSE(puck.nColumn, puck.nRow) && !bDeflect) + { + bDeflect = TRUE; + nDeflectPointX = puck.nColumn; + nDeflectPointY = puck.nRow; + if (Platform_Random(10) == 0) + { + bSteal = TRUE; + } + else + { + Hockey_PlaySound(HOCKEY_SOUND_DEFLECT, PLAYSOUNDFLAGS_PRIORITY); + Platform_Pause(120); + } + } + + if (--nTimerPuckMove <= 0) + { + nTimerPuckMove = TIME_PUCKMOVE; + + // handle the puck behind the goal + + if ((puck.nRow < 2) + || ((puck.nRow == 2) && (puck.nColumn == 0)) + || ((puck.nRow == 2) && (puck.nColumn == 4))) + { + if ((puck.nColumn == 2) && (puck.nRow == 1)) + { + // ** goal! ** + nPenalty = 0; + nPenaltyTimer = 0; + nBehindGoalDirX = 0; + nPuckDirectionX = 0; + nPuckDirectionY = 0; + + Hockey_ClearScreen(); + fsm = FSM_GOAL; + return; + } + + if ((nPuckDirectionY == -1) + && !nBehindGoalDirX) + { + if (puck.nColumn < 2) + { + nBehindGoalDirX = 1; + } + else if (puck.nColumn > 2) + { + nBehindGoalDirX = -1; + } + } + + if (nBehindGoalDirX == 1) + { + if ((puck.nColumn == 0) && (puck.nRow == 2)) + { + puck.nColumn = 1; + puck.nRow = 1; + } + else if ((puck.nColumn == 1) && (puck.nRow == 1)) + { + puck.nColumn = 2; + puck.nRow = 0; + } + else if ((puck.nColumn == 2) && (puck.nRow == 0)) + { + puck.nColumn = 3; + puck.nRow = 1; + } + else if ((puck.nColumn == 3) && (puck.nRow == 1)) + { + puck.nColumn = 4; + puck.nRow = 1;// should be 2 but gets incremented below; + nPuckDirectionX = 0; + nPuckDirectionY = 1; + nBehindGoalDirX = 0; + } + } + else if (nBehindGoalDirX == -1) + { + if ((puck.nColumn == 4) && (puck.nRow == 2)) + { + puck.nColumn = 3; + puck.nRow = 1; + } + else if ((puck.nColumn == 3) && (puck.nRow == 1)) + { + puck.nColumn = 2; + puck.nRow = 0; + } + else if ((puck.nColumn == 2) && (puck.nRow == 0)) + { + puck.nColumn = 1; + puck.nRow = 1; + } + else if ((puck.nColumn == 1) && (puck.nRow == 1)) + { + puck.nColumn = 0; + puck.nRow = 1;// should be 2 but gets incremented below + nPuckDirectionX = 0; + nPuckDirectionY = 1; + nBehindGoalDirX = 0; + } + } + + } + + // handle the puck hitting the walls + + if ((puck.nColumn <= 0) && (nPuckDirectionX == -1)) + { + // bounce off left wall + puck.nColumn = 0; + do { + // pick a new direction + nPuckDirectionX = Platform_Random(2); + switch(Platform_Random(4)) + { + case 0: + nPuckDirectionY = -1; + break; + case 1: + nPuckDirectionY = 0; + break; + default: + // puck is more likely to go up + nPuckDirectionY = 1; + } + } while ((nPuckDirectionX==0) && (nPuckDirectionY==0)); + } + else if ((puck.nColumn >= (HOCKEY_BLIP_COLUMNS-1)) && (nPuckDirectionX == 1)) + { + // bounce off right wall + puck.nColumn = (HOCKEY_BLIP_COLUMNS-1); + do { + // pick a new direction + nPuckDirectionX = -(Platform_Random(2)); + switch(Platform_Random(4)) + { + case 0: + nPuckDirectionY = -1; + break; + case 1: + nPuckDirectionY = 0; + break; + default: + // puck is more likely to go up + nPuckDirectionY = 1; + } + } while ((nPuckDirectionX==0) && (nPuckDirectionY==0)); + } + + if ((puck.nRow >= (HOCKEY_BLIP_ROWS-1)) && (nPuckDirectionY == 1)) + { + // bounce off rear wall + puck.nRow = (HOCKEY_BLIP_ROWS-1); + if ((nPuckDirectionX == 0) + && ((puck.nColumn == 0) || (puck.nColumn == (HOCKEY_BLIP_COLUMNS-1)))) + { + // puck follows the sides + nPuckDirectionY = - 1; + } + else { + do { + // pick a new direction + if (puck.nColumn <= 0) + { + nPuckDirectionX = Platform_Random(2); + } + else if (puck.nColumn >= (HOCKEY_BLIP_COLUMNS-1)) + { + nPuckDirectionX = -(Platform_Random(2)); + } + else + { + nPuckDirectionX = Platform_Random(3) - 1; + } + nPuckDirectionY = -(Platform_Random(2)); + } while ((nPuckDirectionX==0) && (nPuckDirectionY==0)); + } + } + + // the puck has hit a defender +// if (ISDEFENSE(puck.nColumn, puck.nRow)) + if (bDeflect) + { + // let the defenders try to steal the puck + //if (Platform_Random(10) == 0) + if (bSteal) + { + nPenalty = 0; + nPenaltyTimer = 0; + nBehindGoalDirX = 0; + nPuckDirectionX = 0; + nPuckDirectionY = 0; + + Hockey_ClearScreen(); + Hockey_PlaySound(HOCKEY_SOUND_STEAL, PLAYSOUNDFLAGS_PRIORITY); + + UNSETPLAYER(puck); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + + Platform_IsNewSecond(); + bShoot = FALSE; + bDeflect = FALSE; + bSteal = FALSE; + return; + } + else + { + // bounce the puck off the defender + if (GETPLAYERAT(puck.nColumn, puck.nRow) == 0) + { + // goalie always hits the puck down (i think) + nPuckDirectionY = 1; + nPuckDirectionX = Platform_Random(3)-1; + } + else + { + if (nDeflectPointY >= 2) + { + do { + // pick a new direction + if (puck.nColumn <= 0) + { + nPuckDirectionX = Platform_Random(2); + } + else if (puck.nColumn >= (HOCKEY_BLIP_COLUMNS-1)) + { + nPuckDirectionX = -(Platform_Random(2)); + } + else + { + nPuckDirectionX = Platform_Random(3) - 1; + } + + if (puck.nRow <= 0) + { + nPuckDirectionY = Platform_Random(2); + } + else if (puck.nRow >= (HOCKEY_BLIP_ROWS-1)) + { + nPuckDirectionY = -(Platform_Random(2)); + } + else + { + nPuckDirectionY = Platform_Random(3) - 1; + } + } while ((nPuckDirectionX==0) && (nPuckDirectionY==0)); + } + } + } + } + // see if player has regained possession + else if (ISPLAYER(puck.nColumn, puck.nRow) && !bShoot) + { + UNSETPLAYER(puck); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + } + + // move the puck + if (!nBehindGoalDirX) + { + puck.nColumn += nPuckDirectionX; + puck.nRow += nPuckDirectionY; + + // special check for hitting the corners on the curve + if ((puck.nColumn == 0) && (puck.nRow == 1)) + { + puck.nColumn = 1; + puck.nRow = 1; + nBehindGoalDirX = 1; + } + else if ((puck.nColumn == 4) && (puck.nRow == 1)) + { + puck.nColumn = 3; + puck.nRow = 1; + nBehindGoalDirX = -1; + } + } + + bDeflect = FALSE; + bSteal = FALSE; + bShoot = FALSE; + } + } + + // count down the clock + if (Platform_IsNewSecond()){ + // check for end of quarter + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime < 0.1) + { + // end of period + nPenalty = 0; + nPenaltyTimer = 0; + + fGameTime = 0.0; + + ++nPeriod; + if (nPeriod == 3) + { + // game over + bGameOver = TRUE; + + // show formation + { + SETPLAYER(player, 4, 4, BLIP_BRIGHT); + UNSETPLAYER(puck); + SETPLAYER(defense[0], 2, 2, BLIP_DIM); + SETPLAYER(defense[1], 1, 2, BLIP_DIM); + SETPLAYER(defense[2], 3, 2, BLIP_DIM); + SETPLAYER(defense[3], 2, 3, BLIP_DIM); + } + + Hockey_ClearScreen(); + Hockey_PlaySound(HOCKEY_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + else + { + // random possession + bHomeTeam = Platform_Random(2) == 0 ? TRUE : FALSE; + PlatformSetInput(bHomeTeam); + } + + fGameTime = 20.0; + Hockey_ClearScreen(); + Hockey_PlaySound(HOCKEY_SOUND_ENDPERIOD, PLAYSOUNDFLAGS_PRIORITY); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + else + { + // see if its time for the penalty to be over + if (nPenalty && (nPenaltyTimer > 0)) + { + --nPenaltyTimer; + if (nPenaltyTimer <= 0) + { + // take the player out of penalty + int x, y; + do + { + x = Platform_Random(HOCKEY_BLIP_COLUMNS); + y = Platform_Random(HOCKEY_BLIP_ROWS); + } while (ISOCCUPIED(x, y)); + + SETPLAYER(defense[3], x, y, BLIP_DIM); + nPenalty = 0; + nPenaltyTimer = 0; + } + } + } + } + } + + Hockey_DrawStat((int)fGameTime); + + // make tick sounds + if (fGameTime >= .1){ + if (--nTimerTickTimer <= 0){ + Hockey_PlaySound(HOCKEY_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + nTimerTickTimer = bPro2 ? TIME_TICKTIMERPRO2 : TIME_TICKTIMERPRO1; + } + } +} + +void fsmGoal() +{ + Hockey_PlaySound(HOCKEY_SOUND_SCORE, PLAYSOUNDFLAGS_PRIORITY); + + UNSETPLAYER(puck); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + + if (bHomeTeam) + { + nHScore += 1; + } + else + { + nVScore += 1; + } + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + + Platform_IsNewSecond(); + bShoot = FALSE; +} + +void fsmGameOver() +{ + // show stats if pressed 'down' + BOOL bChange; + if (Hockey_GetInputDOWN(&bChange)) + { + if (bChange) + { + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + fsmShowStats(); + return; + } + } + + Hockey_DrawStat(0); +} + diff --git a/source/game/Hockey.h b/source/game/Hockey.h new file mode 100644 index 0000000..acb5656 --- /dev/null +++ b/source/game/Hockey.h @@ -0,0 +1,66 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __HOCKEY_H__ +#define __HOCKEY_H__ + +#include "Platform.h" +#include "Platform_Hockey.h" + + +#define HOCKEY_BLIP_ROWS 5 +#define HOCKEY_BLIP_COLUMNS 5 + +#define HOCKEY_SOUND_TICK 0 +#define HOCKEY_SOUND_DEFLECT 1 +#define HOCKEY_SOUND_BUMP 2 +#define HOCKEY_SOUND_POKE 3 +#define HOCKEY_SOUND_SCORE 4 +#define HOCKEY_SOUND_PENALTY 5 +#define HOCKEY_SOUND_STEAL 6 +#define HOCKEY_SOUND_ENDPERIOD 7 +#define HOCKEY_SOUND_ENDGAME 8 + +void Hockey_Run(); +void Hockey_SetSkill(int i); +int Hockey_GetSkill(); +void Hockey_PowerOn(); +void Hockey_PowerOff(); +BOOL Hockey_GetPower(); + + +#endif + diff --git a/source/game/HockeyCa.c b/source/game/HockeyCa.c new file mode 100644 index 0000000..1bea5c1 --- /dev/null +++ b/source/game/HockeyCa.c @@ -0,0 +1,1030 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + + +#include "HockeyCa.h" +#include "Games.h" + + +// constants + +#define NUM_DEFENSEPLAYERS 6 + +#define TIME_TICKTIMERPRO1 7 +#define TIME_TICKTIMERPRO2 4 +#define TIME_STATSDISPLAY 5 +#define TIME_PUCKMOVE 5 +#define TIME_DEFLECT 2 + + +typedef int BLIP; + +static BLIP Blips[HOCKEYCA_BLIP_COLUMNS][HOCKEYCA_BLIP_ROWS]; + +// game variables +static BOOL bGameOver; +static BOOL bHomeTeam; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bPro2 = FALSE; + +static int nHScore; +static int nVScore; +static float fGameTime; +static int nPlayTime; +static int nPeriod; +static int nTimerTickTimer; + +static BOOL bShoot; +static int nBallDirectionX; +static int nBallDirectionY; +static int nTimerBallMove; + +static BOOL bDeflect; +static int nTimerDeflect; + +static int nStatsIndex; +static int nTimerStatsDisplay; + +typedef struct PLAYER { + int nColumn; + int nRow; + int nBright; + int nColumnOld; + int nRowOld; +}PLAYER; + +static PLAYER puck; +static PLAYER player; +static PLAYER defense[NUM_DEFENSEPLAYERS]; + +// macros for dealing with the players + +#define SETPLAYERBRIGHTNESS(p,b) { \ + p.nBright = b; \ +} + +#define NOTECURRENTPLAYERPOSITION(p) { \ + p.nColumnOld = p.nColumn; \ + p.nRowOld = p.nRow; \ +} + +#define SETPLAYER(p,x,y,b) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn = x; \ + p.nRow = y; \ + p.nBright = b; \ +} + +#define UNSETPLAYER(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn = -1; \ + p.nRow = -1; \ + p.nBright = BLIP_OFF; \ +} + +#define MOVEPLAYERUP(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nRow--; \ +} +#define MOVEPLAYERDOWN(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nRow++; \ +} +#define MOVEPLAYERLEFT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn--; \ +} +#define MOVEPLAYERRIGHT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn++; \ +} + +static BOOL ISPUCK(int x, int y); +static BOOL ISPUCK(int x, int y) +{ + if ((puck.nColumn == x) + && (puck.nRow == y) + && (puck.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISPLAYER(int x, int y); +static BOOL ISPLAYER(int x, int y) +{ + if ((player.nColumn == x) + && (player.nRow == y) + && (player.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISDEFENSE(int x, int y); +static BOOL ISDEFENSE(int x, int y) +{ + for (int i=0; i HOCKEYCA_BLIP_COLUMNS-1) \ + || (p.nColumn < 0) \ + || (p.nRow > HOCKEYCA_BLIP_ROWS-1) \ + || (p.nRow < 0)) + + +#define ISPLAYERENABLED(p) \ + (p.nBright) + +// evaluates to true if given position can block a shot +#define ISBLOCKINGPOS(x,y) \ + ( ((x)==2 && (y)==0) \ + || ((x)==2 && (y)==1) \ + || ((x)==2 && (y)==2) \ + || ((x)==1 && (y)==1) \ + || ((x)==3 && (y)==1) ) + + +// finite state machine stuff + +static void fsmPlayStartWait(); +static void fsmShowStats(); +static void fsmInPlay(); +static void fsmGoal(); +static void fsmGameOver(); + + +static enum FSM { + FSM_PLAYSTARTWAIT=0, + FSM_SHOWSTATS, + FSM_INPLAY, + FSM_GOAL, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmPlayStartWait, + fsmShowStats, + fsmInPlay, + fsmGoal, + fsmGameOver +}; + + +// proto's +static void InitGame(); +static void DrawBlips(); +static void EraseBlips(); + + +BOOL HockeyCa_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void HockeyCa_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void HockeyCa_PowerOff() +{ + bPower = FALSE; + HockeyCa_StopSound(); +} + +void HockeyCa_SetSkill(int i){ + if (i == 0){ + bPro2 = FALSE; + } else { + bPro2 = TRUE; + } +} + +int HockeyCa_GetSkill(){ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + + nHScore = 0; + nVScore = 0; + fGameTime = (float)20.9; + nPeriod = 0; + bGameOver = FALSE; + bDeflect = FALSE; + + fsm = FSM_PLAYSTARTWAIT; +} + +void HockeyCa_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < HOCKEYCA_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEYCA_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + if (!bPower){ + HockeyCa_ClearScreen(); + bInFrame = FALSE; + return; + } + + Platform_StartDraw(); + + (fsmfcn[fsm])(); + + DrawBlips(); + + Platform_EndDraw(); + + bInFrame = FALSE; + +} + +void DrawBlips() +{ + int x, y, nBright; + static BOOL bBlink = FALSE; + + if(fsm != FSM_GOAL) { + for (int i=0; i 0) + && (!ISOCCUPIED(player.nColumn-1, player.nRow))){ + MOVEPLAYERLEFT(player); + } + } + } + else if (HockeyCa_GetInputRIGHT(&bChange)) + { + if (bChange) + { + if ((player.nColumn < (HOCKEYCA_BLIP_COLUMNS-1)) + && (!ISOCCUPIED(player.nColumn+1, player.nRow))){ + MOVEPLAYERRIGHT(player); + } + } + } + else if (HockeyCa_GetInputUP(&bChange)) + { + if (bChange) + { + if ((player.nRow > 0) + && (!ISOCCUPIED(player.nColumn, player.nRow-1))){ + MOVEPLAYERUP(player); + } + } + } + else if (HockeyCa_GetInputDOWN(&bChange)) + { + if (bChange) + { + if ((player.nRow < (HOCKEYCA_BLIP_ROWS-1)) + && (!ISOCCUPIED(player.nColumn, player.nRow+1))){ + MOVEPLAYERDOWN(player); + } + } + } + + if (nTimerDeflect) + { + // still in deflect + --nTimerDeflect; + return; + } + + if (HockeyCa_GetInputTHROW(&bChange)) + { + if (bChange) + { + if (!ISPLAYERENABLED(puck)) + { + // shoot! + bShoot = TRUE; + nTimerBallMove = TIME_PUCKMOVE; + SETPLAYERBRIGHTNESS(player, BLIP_DIMBLINK); + SETPLAYER(puck, player.nColumn, player.nRow, BLIP_BRIGHT); + + if (player.nRow > 0) + { + nBallDirectionY = -1; + } + else + { + nBallDirectionY = 0; + } + + if (player.nColumn < 2) + { + nBallDirectionX = 1; + } + else if (player.nColumn > 2) + { + nBallDirectionX = -1; + } + else + { + nBallDirectionX = 0; + } + } + } + } + + + // move the two end defenders randomly + { + if (Platform_Random(bPro2 ? 10 : 20) == 0){ + // move horizontally or vertically + int x = defense[1].nColumn; + int y = defense[1].nRow; + if (Platform_Random(2)){ + if (x == 0){ + x = 1; + } else { + x = 0; + } + } else { + if (y == 0){ + y = 1; + } else { + y = 0; + } + } + if (!ISOCCUPIED(x,y)) + { + // if puck is active, only move defender + // if it will block the shot + if ((ISPLAYERENABLED(puck) && ISBLOCKINGPOS(x,y)) + || (!ISPLAYERENABLED(puck))) + { + SETPLAYER(defense[1], x, y, BLIP_DIM); + } + } + } + if (Platform_Random(bPro2 ? 10 : 20) == 0){ + // move horizontally or vertically + int x = defense[2].nColumn; + int y = defense[2].nRow; + if (Platform_Random(2)){ + if (x == (HOCKEYCA_BLIP_COLUMNS-1)){ + x = (HOCKEYCA_BLIP_COLUMNS-2); + } else { + x = (HOCKEYCA_BLIP_COLUMNS-1); + } + } else { + if (y == 0){ + y = 1; + } else { + y = 0; + } + } + if (!ISOCCUPIED(x,y)) + { + // if puck is active, only move defender + // if it will block the shot + if ((ISPLAYERENABLED(puck) && ISBLOCKINGPOS(x,y)) + || (!ISPLAYERENABLED(puck))) + { + SETPLAYER(defense[2], x, y, BLIP_DIM); + } + } + } + } + + // establish a target for the defense + PLAYER *targetP = ISPLAYERENABLED(puck) ? &puck : &player; + + // move the goalie + { + // decide if the goalie will move this frame - + if (Platform_Random(bPro2 ? 6 : 8) == 0) + { + // pick a direction + if ((targetP->nRow == 1) + && (defense[0].nRow == 0) + && (defense[0].nColumn == targetP->nColumn) + && (Platform_Random(2) == 0)) + + { + // puck is loose - move out of goal area if we can deflect the puck + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the puck + if (!ISDEFENSE(defense[0].nColumn, 1)) + { + defense[0].nRow = 1; + } + } + else + { + if (defense[0].nRow == 1) + { + // move back to row 0 to protect goal + if (Platform_Random(3) == 0) + { + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the puck + if (!ISDEFENSE(defense[0].nColumn, 0)) + { + defense[0].nRow = 0; + } + } + } + else + { + // horizontally + if ((targetP->nColumn < defense[0].nColumn) + && (defense[0].nColumn > 1)) + { + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the puck + if (!ISDEFENSE(defense[0].nColumn-1, defense[0].nRow)) + { + defense[0].nColumn--; + } + } + else if ((targetP->nColumn > defense[0].nColumn) + && (defense[0].nColumn < 3)) + { + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the puck + if (!ISDEFENSE(defense[0].nColumn+1, defense[0].nRow)) + { + defense[0].nColumn++; + } + } + } + } + + // check for goalie intercepting the puck + if ((targetP->nColumn == defense[0].nColumn) + && (targetP->nRow == defense[0].nRow)) + { + if (ISPLAYERENABLED(puck)) + { + // deflect it - handled below by the puck move code + } + else + { + // got the puck while the player still had possession - interception + bShoot = FALSE; + UNSETPLAYER(puck); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + HockeyCa_ClearScreen(); + HockeyCa_PlaySound(HOCKEYCA_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + + } + } + + // middle defenders try to roughly occupy the + // midpoint between the player and the goal + { + int midx = (player.nColumn + 2) / 2; + int midy = (player.nRow + 1) / 2; + + // decide if a defender will move this frame - + if (Platform_Random(bPro2 ? 2 : 5) == 0) + { + // pick a random defender + static int nDefenderLast = -1; + int nDefender = Platform_Random(3); + + if (nDefender != nDefenderLast) + { + nDefenderLast = nDefender; + + PLAYER *pDefender; + switch(nDefender) + { + case 0: + pDefender = &defense[3]; + break; + case 1: + pDefender = &defense[4]; + break; + case 2: + pDefender = &defense[5]; + break; + } + + int dx = pDefender->nColumn; + int dy = pDefender->nRow; + + // randomly move the defender towards the midpoint + if (Platform_Random(2)) + { + if (dx < midx) + { + ++dx; + } + else if (dx > midx) + { + --dx; + } + } + else + { + if (dy < midy) + { + ++dy; + } + else if (dy > midy) + { + --dy; + } + } + + // occasionally randomly offset the defender's position + if (Platform_Random(5) == 0) + { + if (Platform_Random(2)) + { + dx += (Platform_Random(2)) ? 1 : -1; + } + else + { + dy += (Platform_Random(2)) ? 1 : -1; + } + } + + // make sure the defender does not step on anybody, + // and keep him confined to the proper area + if (!ISOCCUPIED(dx, dy) + && (dx > 0) + && (dx < (HOCKEYCA_BLIP_COLUMNS - 1)) + && (dy >= 0) + && (dy < (HOCKEYCA_BLIP_ROWS - 1))) + { + // if puck is active, only move defender + // if it will block the shot + if ((ISPLAYERENABLED(puck) && ISBLOCKINGPOS(dx,dy)) + || (!ISPLAYERENABLED(puck))) + { + SETPLAYER((*pDefender), dx, dy, BLIP_DIM); + } + } + + } + } + } + + // move the puck + if (ISPLAYERENABLED(puck)) + { + // the puck hit a defender last frame - play the sound + if (ISDEFENSE(puck.nColumn, puck.nRow) && !bDeflect) + { + bDeflect = TRUE; + HockeyCa_PlaySound(HOCKEYCA_SOUND_BOUNCE, PLAYSOUNDFLAGS_PRIORITY); + nTimerDeflect = TIME_DEFLECT; + return; + } + + if (--nTimerBallMove <= 0) + { + nTimerBallMove = TIME_PUCKMOVE; + + // check for a goal + if ((puck.nColumn == 2) && (puck.nRow == 0) + && !ISDEFENSE(puck.nColumn, puck.nRow)) // <-- is this right? + { + // goal! + puck.nRow = -1; + HockeyCa_DrawGoal(TRUE); + fsm = FSM_GOAL; + return; + } + + // bounce the puck off the defenders + if (bDeflect) + { + Platform_IsNewSecond(); + nBallDirectionX = Platform_Random(3) - 1; + nBallDirectionY = 1; + bDeflect = FALSE; + } + + // see if player has regained possession + if (ISPLAYER(puck.nColumn, puck.nRow) && !bShoot) + { + UNSETPLAYER(puck); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + nPlayTime = 50; // reset play timer + } + else + { + // move the puck + puck.nColumn += nBallDirectionX; + puck.nRow += nBallDirectionY; + bShoot = FALSE; + + // see if the puck bounced off the screen + if (ISPLAYEROFFSCREEN(puck) && ISPLAYERENABLED(puck)) + { + // off the screen - get rid of it and end the play + bShoot = FALSE; + UNSETPLAYER(puck); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + HockeyCa_ClearScreen(); + HockeyCa_PlaySound(HOCKEYCA_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + } + } + + // count down the clock + if (Platform_IsNewSecond()){ + // check for end of period + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime < 0.1){ + + // end of period + + ++nPeriod; + if (nPeriod == 3) + { + // game over + bGameOver = TRUE; + + HockeyCa_ClearScreen(); + HockeyCa_PlaySound(HOCKEYCA_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + + // show formation + { + SETPLAYER(player, 0, 3, BLIP_BRIGHT); + UNSETPLAYER(puck); + + SETPLAYER(defense[0], 2, 0, BLIP_DIMFLICKER); + + SETPLAYER(defense[1], 0, 1, BLIP_DIM); + SETPLAYER(defense[2], 4, 1, BLIP_DIM); + SETPLAYER(defense[3], 1, 1, BLIP_DIM); + SETPLAYER(defense[4], 3, 1, BLIP_DIM); + + SETPLAYER(defense[5], 3, 2, BLIP_DIM); + } + + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + else + { + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + } + + fGameTime = (float)20.9; + HockeyCa_ClearScreen(); + HockeyCa_PlaySound(HOCKEYCA_SOUND_ENDQUARTER, PLAYSOUNDFLAGS_PRIORITY); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + // check for end of play timer + if (--nPlayTime < 0){ + HockeyCa_ClearScreen(); + HockeyCa_PlaySound(HOCKEYCA_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + + HockeyCa_DrawStat((int)fGameTime); + + // make tick sounds + if (fGameTime >= .1){ + if (--nTimerTickTimer <= 0){ + HockeyCa_PlaySound(HOCKEYCA_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + nTimerTickTimer = bPro2 ? TIME_TICKTIMERPRO2 : TIME_TICKTIMERPRO1; + } + } +} + +void fsmGoal() +{ + HockeyCa_PlaySound(HOCKEYCA_SOUND_SCORE, PLAYSOUNDFLAGS_PRIORITY); + HockeyCa_DrawGoal(FALSE); + if (bHomeTeam) + { + nHScore += 1; + } + else + { + nVScore += 1; + } + + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; +} + +void fsmGameOver() +{ + // show stats if pressed 'down' + BOOL bChange; + if (HockeyCa_GetInputDOWN(&bChange)) + { + if (bChange) + { + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + fsmShowStats(); + return; + } + } + + HockeyCa_DrawStat(0); +} + diff --git a/source/game/HockeyCa.h b/source/game/HockeyCa.h new file mode 100644 index 0000000..b100945 --- /dev/null +++ b/source/game/HockeyCa.h @@ -0,0 +1,63 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __HOCKEYCA_H__ +#define __HOCKEYCA_H__ + +#include "Platform.h" +#include "Platform_HockeyCa.h" + + +#define HOCKEYCA_BLIP_ROWS 4 +#define HOCKEYCA_BLIP_COLUMNS 5 + +#define HOCKEYCA_SOUND_TICK 0 +#define HOCKEYCA_SOUND_BOUNCE 1 +#define HOCKEYCA_SOUND_SCORE 2 +#define HOCKEYCA_SOUND_ENDPLAY 3 +#define HOCKEYCA_SOUND_ENDQUARTER 4 +#define HOCKEYCA_SOUND_ENDGAME 5 + +void HockeyCa_Run(); +void HockeyCa_SetSkill(int i); +int HockeyCa_GetSkill(); +void HockeyCa_PowerOn(); +void HockeyCa_PowerOff(); +BOOL HockeyCa_GetPower(); + + +#endif + diff --git a/source/game/Soccer.c b/source/game/Soccer.c new file mode 100644 index 0000000..4841a5c --- /dev/null +++ b/source/game/Soccer.c @@ -0,0 +1,1021 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + + +#include "Soccer.h" +#include "Games.h" + + +// constants + +#define NUM_DEFENSEPLAYERS 6 + +#define TIME_TICKTIMERPRO1 7 +#define TIME_TICKTIMERPRO2 4 +#define TIME_STATSDISPLAY 5 +#define TIME_BALLMOVE 5 +#define TIME_DEFLECT 2 + + +typedef int BLIP; + +static BLIP Blips[SOCCER_BLIP_COLUMNS][SOCCER_BLIP_ROWS]; + +// game variables +static BOOL bGameOver; +static BOOL bHomeTeam; +static BOOL bInFrame = FALSE; +static BOOL bPower; +static BOOL bPro2 = FALSE; + +static int nHScore; +static int nVScore; +static float fGameTime; +static int nPlayTime; +static int nPeriod; +static int nTimerTickTimer; + +static BOOL bShoot; +static int nBallDirectionX; +static int nBallDirectionY; +static int nTimerBallMove; + +static BOOL bDeflect; +static int nTimerDeflect; + +static int nStatsIndex; +static int nTimerStatsDisplay; + +typedef struct PLAYER { + int nColumn; + int nRow; + int nBright; + int nColumnOld; + int nRowOld; +}PLAYER; + +static PLAYER ball; +static PLAYER player; +static PLAYER defense[NUM_DEFENSEPLAYERS]; + +// macros for dealing with the players + +#define SETPLAYERBRIGHTNESS(p,b) { \ + p.nBright = b; \ +} + +#define NOTECURRENTPLAYERPOSITION(p) { \ + p.nColumnOld = p.nColumn; \ + p.nRowOld = p.nRow; \ +} + +#define SETPLAYER(p,x,y,b) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn = x; \ + p.nRow = y; \ + p.nBright = b; \ +} + +#define UNSETPLAYER(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn = -1; \ + p.nRow = -1; \ + p.nBright = BLIP_OFF; \ +} + +#define MOVEPLAYERUP(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nRow--; \ +} +#define MOVEPLAYERDOWN(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nRow++; \ +} +#define MOVEPLAYERLEFT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn--; \ +} +#define MOVEPLAYERRIGHT(p) { \ + NOTECURRENTPLAYERPOSITION(p); \ + p.nColumn++; \ +} + +static BOOL ISBALL(int x, int y); +static BOOL ISBALL(int x, int y) +{ + if ((ball.nColumn == x) + && (ball.nRow == y) + && (ball.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISPLAYER(int x, int y); +static BOOL ISPLAYER(int x, int y) +{ + if ((player.nColumn == x) + && (player.nRow == y) + && (player.nBright)){ + return TRUE; + } + return FALSE; +} + +static BOOL ISDEFENSE(int x, int y); +static BOOL ISDEFENSE(int x, int y) +{ + for (int i=0; i SOCCER_BLIP_COLUMNS-1) \ + || (p.nColumn < 0) \ + || (p.nRow > SOCCER_BLIP_ROWS-1) \ + || (p.nRow < 0)) + + +#define ISPLAYERENABLED(p) \ + (p.nBright) + +// evaluates to true if given position can block a shot +#define ISBLOCKINGPOS(x,y) \ + ( ((x)==2 && (y)==0) \ + || ((x)==2 && (y)==1) \ + || ((x)==2 && (y)==2) \ + || ((x)==1 && (y)==1) \ + || ((x)==3 && (y)==1) ) + + +// finite state machine stuff + +static void fsmPlayStartWait(); +static void fsmShowStats(); +static void fsmInPlay(); +static void fsmGoal(); +static void fsmGameOver(); + + +static enum FSM { + FSM_PLAYSTARTWAIT=0, + FSM_SHOWSTATS, + FSM_INPLAY, + FSM_GOAL, + FSM_GAMEOVER +}fsm; + +typedef void (*FSMFCN)(); + +static FSMFCN fsmfcn[] = { + fsmPlayStartWait, + fsmShowStats, + fsmInPlay, + fsmGoal, + fsmGameOver +}; + + +// proto's +static void InitGame(); +static void DrawBlips(); +static void EraseBlips(); + + +BOOL Soccer_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void Soccer_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void Soccer_PowerOff() +{ + bPower = FALSE; + Soccer_StopSound(); +} + +void Soccer_SetSkill(int i){ + if (i == 0){ + bPro2 = FALSE; + } else { + bPro2 = TRUE; + } +} + +int Soccer_GetSkill(){ + return bPro2 ? 1 : 0; +} + +void InitGame() +{ + bHomeTeam = FALSE; + PlatformSetInput(bHomeTeam); + + nHScore = 0; + nVScore = 0; + fGameTime = 45.9; + nPeriod = 0; + bGameOver = FALSE; + bDeflect = FALSE; + + fsm = FSM_PLAYSTARTWAIT; +} + +void Soccer_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < SOCCER_BLIP_ROWS; y++){ + for (x = 0; x < SOCCER_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + if (!bPower){ + Soccer_ClearScreen(); + bInFrame = FALSE; + return; + } + Platform_StartDraw(); + + (fsmfcn[fsm])(); + + DrawBlips(); + + Platform_EndDraw(); + + bInFrame = FALSE; + +} + +void DrawBlips() +{ + int x, y, nBright; + static BOOL bBlink = FALSE; + + if(fsm != FSM_GOAL) { + for (int i=0; i 0) + && (!ISOCCUPIED(player.nColumn-1, player.nRow))){ + MOVEPLAYERLEFT(player); + } + } + } + else if (Soccer_GetInputRIGHT(&bChange)) + { + if (bChange) + { + if ((player.nColumn < (SOCCER_BLIP_COLUMNS-1)) + && (!ISOCCUPIED(player.nColumn+1, player.nRow))){ + MOVEPLAYERRIGHT(player); + } + } + } + else if (Soccer_GetInputUP(&bChange)) + { + if (bChange) + { + if ((player.nRow > 0) + && (!ISOCCUPIED(player.nColumn, player.nRow-1))){ + MOVEPLAYERUP(player); + } + } + } + else if (Soccer_GetInputDOWN(&bChange)) + { + if (bChange) + { + if ((player.nRow < (SOCCER_BLIP_ROWS-1)) + && (!ISOCCUPIED(player.nColumn, player.nRow+1))){ + MOVEPLAYERDOWN(player); + } + } + } + + if (nTimerDeflect) + { + // still in deflect + --nTimerDeflect; + return; + } + + if (Soccer_GetInputTHROW(&bChange)) + { + if (bChange) + { + if (!ISPLAYERENABLED(ball)) + { + // shoot! + bShoot = TRUE; + nTimerBallMove = TIME_BALLMOVE; + SETPLAYERBRIGHTNESS(player, BLIP_DIMBLINK); + SETPLAYER(ball, player.nColumn, player.nRow, BLIP_BRIGHT); + + if (player.nRow > 0) + { + nBallDirectionY = -1; + } + else + { + nBallDirectionY = 0; + } + + if (player.nColumn < 2) + { + nBallDirectionX = 1; + } + else if (player.nColumn > 2) + { + nBallDirectionX = -1; + } + else + { + nBallDirectionX = 0; + } + } + } + } + + + // move the two end defenders randomly + { + if (Platform_Random(bPro2 ? 10 : 20) == 0){ + // move horizontally or vertically + int x = defense[1].nColumn; + int y = defense[1].nRow; + if (Platform_Random(2)){ + if (x == 0){ + x = 1; + } else { + x = 0; + } + } else { + if (y == 0){ + y = 1; + } else { + y = 0; + } + } + if (!ISOCCUPIED(x,y)){ + SETPLAYER(defense[1], x, y, BLIP_DIM); + } + } + if (Platform_Random(bPro2 ? 10 : 20) == 0){ + // move horizontally or vertically + int x = defense[2].nColumn; + int y = defense[2].nRow; + if (Platform_Random(2)){ + if (x == (SOCCER_BLIP_COLUMNS-1)){ + x = (SOCCER_BLIP_COLUMNS-2); + } else { + x = (SOCCER_BLIP_COLUMNS-1); + } + } else { + if (y == 0){ + y = 1; + } else { + y = 0; + } + } + if (!ISOCCUPIED(x,y)) + { + // if ball is active, only move defender + // if it will block the shot + if ((ISPLAYERENABLED(ball) && ISBLOCKINGPOS(x,y)) + || (!ISPLAYERENABLED(ball))) + { + SETPLAYER(defense[2], x, y, BLIP_DIM); + } + } + } + } + + // establish a target for the defense + PLAYER *targetP = ISPLAYERENABLED(ball) ? &ball : &player; + + // move the goalie + { + // decide if the goalie will move this frame - + if (Platform_Random(bPro2 ? 6 : 8) == 0) + { + // pick a direction + if ((targetP->nRow == 1) + && (defense[0].nRow == 0) + && (defense[0].nColumn == targetP->nColumn) + && (Platform_Random(2) == 0)) + + { + // ball is loose - move out of goal area if we can deflect the ball + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the ball + if (!ISDEFENSE(defense[0].nColumn, 1)) + { + defense[0].nRow = 1; + } + } + else + { + if (defense[0].nRow == 1) + { + // move back to row 0 to protect goal + if (Platform_Random(3) == 0) + { + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the ball + if (!ISDEFENSE(defense[0].nColumn, 0)) + { + defense[0].nRow = 0; + } + } + } + else + { + // horizontally + if ((targetP->nColumn < defense[0].nColumn) + && (defense[0].nColumn > 1)) + { + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the ball + if (!ISDEFENSE(defense[0].nColumn-1, defense[0].nRow)) + { + defense[0].nColumn--; + } + } + else if ((targetP->nColumn > defense[0].nColumn) + && (defense[0].nColumn < 3)) + { + // notice we only check here for defenders - it is intentionally + // possible for the goalie to move on top of the player and + // thus intercept the ball + if (!ISDEFENSE(defense[0].nColumn+1, defense[0].nRow)) + { + defense[0].nColumn++; + } + } + } + } + + // check for goalie intercepting the ball + if ((targetP->nColumn == defense[0].nColumn) + && (targetP->nRow == defense[0].nRow)) + { + if (ISPLAYERENABLED(ball)) + { + // deflect it - handled below by the ball move code + } + else + { + // got the ball while the player still had possession - interception + bShoot = FALSE; + UNSETPLAYER(ball); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + Soccer_ClearScreen(); + Soccer_PlaySound(SOCCER_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + + } + } + + // middle defenders try to roughly occupy the + // midpoint between the player and the goal + { + int midx = (player.nColumn + 2) / 2; + int midy = (player.nRow + 1) / 2; + + // decide if a defender will move this frame - + if (Platform_Random(bPro2 ? 2 : 5) == 0) + { + // pick a random defender + static int nDefenderLast = -1; + int nDefender = Platform_Random(3); + + if (nDefender != nDefenderLast) + { + nDefenderLast = nDefender; + + PLAYER *pDefender; + switch(nDefender) + { + case 0: + pDefender = &defense[3]; + break; + case 1: + pDefender = &defense[4]; + break; + case 2: + pDefender = &defense[5]; + break; + } + + int dx = pDefender->nColumn; + int dy = pDefender->nRow; + + // randomly move the defender towards the midpoint + if (Platform_Random(2)) + { + if (dx < midx) + { + ++dx; + } + else if (dx > midx) + { + --dx; + } + } + else + { + if (dy < midy) + { + ++dy; + } + else if (dy > midy) + { + --dy; + } + } + + // occasionally randomly offset the defender's position + if (Platform_Random(5) == 0) + { + if (Platform_Random(2)) + { + dx += (Platform_Random(2)) ? 1 : -1; + } + else + { + dy += (Platform_Random(2)) ? 1 : -1; + } + } + + // make sure the defender does not step on anybody, + // and keep him confined to the proper area + if (!ISOCCUPIED(dx, dy) + && (dx > 0) + && (dx < (SOCCER_BLIP_COLUMNS - 1)) + && (dy >= 0) + && (dy < (SOCCER_BLIP_ROWS - 1))) + { + // if ball is active, only move defender + // if it will block the shot + if ((ISPLAYERENABLED(ball) && ISBLOCKINGPOS(dx,dy)) + || (!ISPLAYERENABLED(ball))) + { + SETPLAYER((*pDefender), dx, dy, BLIP_DIM); + } + } + + } + } + } + + // move the ball + if (ISPLAYERENABLED(ball)) + { + // the puck hit a defender last frame - play the sound + if (ISDEFENSE(ball.nColumn, ball.nRow) && !bDeflect) + { + bDeflect = TRUE; + Soccer_PlaySound(SOCCER_SOUND_BOUNCE, PLAYSOUNDFLAGS_PRIORITY); + nTimerDeflect = TIME_DEFLECT; + return; + } + + if (--nTimerBallMove <= 0) + { + nTimerBallMove = TIME_BALLMOVE; + + // check for a goal + if ((ball.nColumn == 2) && (ball.nRow == 0) + && !ISDEFENSE(ball.nColumn, ball.nRow)) // <-- is this right? + { + // goal! + ball.nRow = -1; + Soccer_DrawGoal(TRUE); + fsm = FSM_GOAL; + return; + } + + // bounce the ball off the defenders + if (bDeflect) + { + Platform_IsNewSecond(); + nBallDirectionX = Platform_Random(3) - 1; + nBallDirectionY = 1; + bDeflect = FALSE; + } + + // see if player has regained possession + if (ISPLAYER(ball.nColumn, ball.nRow) && !bShoot) + { + UNSETPLAYER(ball); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + nPlayTime = 100; // reset play timer + } + else + { + // move the ball + ball.nColumn += nBallDirectionX; + ball.nRow += nBallDirectionY; + bShoot = FALSE; + + // see if the ball bounced off the screen + if (ISPLAYEROFFSCREEN(ball) && ISPLAYERENABLED(ball)) + { + // off the screen - get rid of it and end the play + bShoot = FALSE; + UNSETPLAYER(ball); + SETPLAYERBRIGHTNESS(player, BLIP_BRIGHT); + Soccer_ClearScreen(); + Soccer_PlaySound(SOCCER_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + } + } + + // count down the clock + if (Platform_IsNewSecond()){ + // check for end of period + if (fGameTime > 0.0){ + fGameTime -= (float).1; + if (fGameTime < 0.1){ + + // end of period + + ++nPeriod; + if (nPeriod == 2) + { + // game over + bGameOver = TRUE; + + Soccer_ClearScreen(); + Soccer_PlaySound(SOCCER_SOUND_ENDGAME, PLAYSOUNDFLAGS_PRIORITY); + + // show formation + { + SETPLAYER(player, 4, 3, BLIP_BRIGHT); + UNSETPLAYER(ball); + + SETPLAYER(defense[0], 2, 0, BLIP_DIMFLICKER); + + SETPLAYER(defense[1], 0, 1, BLIP_DIM); + SETPLAYER(defense[2], 4, 1, BLIP_DIM); + SETPLAYER(defense[3], 1, 1, BLIP_DIM); + SETPLAYER(defense[4], 3, 1, BLIP_DIM); + + SETPLAYER(defense[5], 1, 2, BLIP_DIM); + } + + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + else + { + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + } + + fGameTime = 45.9; + Soccer_ClearScreen(); + Soccer_PlaySound(SOCCER_SOUND_ENDQUARTER, PLAYSOUNDFLAGS_PRIORITY); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + // check for end of play timer + if (--nPlayTime < 0){ + Soccer_ClearScreen(); + Soccer_PlaySound(SOCCER_SOUND_ENDPLAY, PLAYSOUNDFLAGS_PRIORITY); + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + return; + } + } + + Soccer_DrawStat((int)fGameTime); + + // make tick sounds + if (fGameTime >= .1){ + if (--nTimerTickTimer <= 0){ + Soccer_PlaySound(SOCCER_SOUND_TICK, PLAYSOUNDFLAGS_ASYNC); + nTimerTickTimer = bPro2 ? TIME_TICKTIMERPRO2 : TIME_TICKTIMERPRO1; + } + } +} + +void fsmGoal() +{ + Soccer_PlaySound(SOCCER_SOUND_SCORE, PLAYSOUNDFLAGS_PRIORITY); + Soccer_DrawGoal(FALSE); + if (bHomeTeam) + { + nHScore += 1; + } + else + { + nVScore += 1; + } + + bHomeTeam = !bHomeTeam; + PlatformSetInput(bHomeTeam); + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; +} + +void fsmGameOver() +{ + // show stats if pressed 'down' + BOOL bChange; + if (Soccer_GetInputDOWN(&bChange)) + { + if (bChange) + { + nStatsIndex = 0; + nTimerStatsDisplay = TIME_STATSDISPLAY; + fsm = FSM_SHOWSTATS; + fsmShowStats(); + return; + } + } + + Soccer_DrawStat(0); +} + diff --git a/source/game/Soccer.h b/source/game/Soccer.h new file mode 100644 index 0000000..eb3742b --- /dev/null +++ b/source/game/Soccer.h @@ -0,0 +1,63 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __SOCCER_H__ +#define __SOCCER_H__ + +#include "Platform.h" +#include "Platform_Soccer.h" + + +#define SOCCER_BLIP_ROWS 4 +#define SOCCER_BLIP_COLUMNS 5 + +#define SOCCER_SOUND_TICK 0 +#define SOCCER_SOUND_BOUNCE 1 +#define SOCCER_SOUND_SCORE 2 +#define SOCCER_SOUND_ENDPLAY 3 +#define SOCCER_SOUND_ENDQUARTER 4 +#define SOCCER_SOUND_ENDGAME 5 + +void Soccer_Run(); +void Soccer_SetSkill(int i); +int Soccer_GetSkill(); +void Soccer_PowerOn(); +void Soccer_PowerOff(); +BOOL Soccer_GetPower(); + + +#endif + diff --git a/source/game/SpaceAlert.c b/source/game/SpaceAlert.c new file mode 100644 index 0000000..c10388c --- /dev/null +++ b/source/game/SpaceAlert.c @@ -0,0 +1,524 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + + +#include "SpaceAlert.h" +#include "Games.h" + + +// constants + +#define TIME_ATTACKWAVE 20 +#define TIME_SHOWHIT 10 + +#define RAIDER_COUNT 20 +//#define MISSILE_LIMIT (-10) +#define MISSILE_LIMIT (-7) + +typedef int BLIP; + +static BLIP Blips[SPACEALERT_BLIP_COLUMNS][SPACEALERT_BLIP_ROWS]; + +typedef struct tagRaider { + int nColumn; + int nRow; + + int nSlow; + + BOOL bAttacking; + + BOOL bLeftColumn; + BOOL bMidColumn; + BOOL bRightColumn; +}RAIDER; + +static RAIDER sRaiderA, sRaiderB; + + +// game variables +static int nColumnSelector; +static int nCurrentMissileRow; +static int nIndexAttackWave; +static int nIndexAttackFrame; +static int nTimerAttackWave; +static int nRaiderCount; +static int nPoints; +static BOOL bGameOver; +static BOOL bWin; +static BOOL bInFrame = FALSE; +static BOOL bPower; + +static void InitGame(); +static void InitAttack(); +static void DoMissileUpdate(); +static void DoRaidersUpdate(); +static void DoHitTest(); +static void UpdateBlips(); +static void PaintGame(); + + +BOOL SpaceAlert_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void SpaceAlert_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void SpaceAlert_PowerOff() +{ + bPower = FALSE; + SpaceAlert_StopSound(); + SpaceAlert_StopRaiderSound(); +} + +void InitGame() +{ + + nColumnSelector = 1; + nCurrentMissileRow = SPACEALERT_BLIP_ROWS - 1; + + nRaiderCount = RAIDER_COUNT; + nIndexAttackWave = 0; + nIndexAttackFrame = 0; + + nTimerAttackWave = 1; + + nPoints = 0; + + bGameOver = FALSE; + bWin = TRUE; + + sRaiderA.bAttacking = FALSE; + +} + + +void SpaceAlert_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < SPACEALERT_BLIP_ROWS; y++){ + for (x = 0; x < SPACEALERT_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + if (bPower){ + if (bGameOver){ + // handle game over + static BOOL bFlash = 0; + if (bWin){ + // win + Blips[0][SPACEALERT_BLIP_ROWS-2] = BLIP_BRIGHT; + Blips[1][SPACEALERT_BLIP_ROWS-2] = BLIP_BRIGHT; + Blips[2][SPACEALERT_BLIP_ROWS-2] = BLIP_BRIGHT; + } else { + // lose + if (bFlash){ + bFlash = FALSE; + Blips[1][SPACEALERT_BLIP_ROWS-1] = BLIP_BRIGHT; + } else { + bFlash = TRUE; + } + } + + // allow stick and fire button to be moved + SpaceAlert_GetInputFIRE(NULL); + SpaceAlert_GetInputSTICK(); + + // draw the frame + PaintGame(); + bInFrame = FALSE; + return; + } + } else { + + // allow stick and fire button to be moved + SpaceAlert_GetInputFIRE(NULL); + SpaceAlert_GetInputSTICK(); + + SpaceAlert_ClearScreen(); + bInFrame = FALSE; + return; + } + + // get the current stick position + nColumnSelector = SpaceAlert_GetInputSTICK(); + + { + DoHitTest(); + + DoRaidersUpdate(); + + UpdateBlips(); + PaintGame(); + + DoHitTest(); + + DoMissileUpdate(); + } + + bInFrame = FALSE; + +} + + +void DoMissileUpdate() +{ + // update the missiles + if (SpaceAlert_GetInputFIRE(NULL)) + { + // fire + if (nCurrentMissileRow == (SPACEALERT_BLIP_ROWS - 1)) + { + SpaceAlert_PlaySound(SPACEALERT_SOUND_FIRE, PLAYSOUNDFLAGS_ASYNC | PLAYSOUNDFLAGS_PRIORITY); + --nCurrentMissileRow; + return; + } + } + + // move any active missiles + if (nCurrentMissileRow < (SPACEALERT_BLIP_ROWS - 1)) + { + if (nCurrentMissileRow >= MISSILE_LIMIT){ + // move missile up the screen + --nCurrentMissileRow; + } else { + // missile has hit its limit offscreen -- show new missile + nCurrentMissileRow = SPACEALERT_BLIP_ROWS - 1; + } + } +} + +void DoRaidersUpdate() +{ + + // update the attack + if (nTimerAttackWave > 0){ + --nTimerAttackWave; + if (nTimerAttackWave == 0){ + // start a new attack wave + nIndexAttackWave = 0; + InitAttack(); + } + } else { + nTimerAttackWave = 0; + } + + // handle the raiders + for (int i=0; i<2; i++){ + + RAIDER *sRaiderP = i ? &sRaiderB : &sRaiderA; + RAIDER *sOtherRaiderP = i ? &sRaiderA : &sRaiderB; + + if (sRaiderP->bAttacking){ + + // raider is attacking + + if (sRaiderP->nSlow){ + // handle the slow raiders + if (sRaiderP->nSlow == 1){ + sRaiderP->nSlow = 2; + } else { + sRaiderP->nSlow = 1; + } + } + + if (sRaiderP->nSlow <= 1){ + + // advance the raider + sRaiderP->nRow++; + + if (sRaiderP->nRow >= SPACEALERT_BLIP_ROWS){ + + // miss + sRaiderP->bAttacking = FALSE; + --nRaiderCount; + + if (sRaiderP->nColumn == 1){ + + // battlestart hit -- lose + // draw a blank screen during the tune + sRaiderA.bAttacking = FALSE; + sRaiderB.bAttacking = FALSE; + nCurrentMissileRow = -1; + SpaceAlert_ClearScreen(); + SpaceAlert_StopRaiderSound(); + SpaceAlert_PlaySound(SPACEALERT_SOUND_LOSE, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + bWin = FALSE; + return; + + } + else if (nRaiderCount <= 0){ + + // no more raiders -- win + // draw a blank screen during the tune + sRaiderA.bAttacking = FALSE; + sRaiderB.bAttacking = FALSE; + nCurrentMissileRow = -1; + SpaceAlert_ClearScreen(); + SpaceAlert_StopRaiderSound(); + SpaceAlert_PlaySound(SPACEALERT_SOUND_WIN, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + bWin = TRUE; + return; + + } else { + // set up next wave + nTimerAttackWave = TIME_ATTACKWAVE; + } + + } + + // change lanes randomly (don't change on last rows) + if (sRaiderP->nRow < SPACEALERT_BLIP_ROWS - 2){ + if (Platform_Random(7) == 0){ + // can only be in each column once per attack + switch(sRaiderP->nColumn){ + case 0: + sRaiderP->bLeftColumn = TRUE; + if ((!sRaiderP->bMidColumn) + && (sOtherRaiderP->nColumn != 1) + && (sRaiderP->nRow != sOtherRaiderP->nRow)) + { + sRaiderP->nColumn = 1; + } + break; + case 1: + sRaiderP->bMidColumn = TRUE; + if (Platform_Random(2)) + { + if ((!sRaiderP->bLeftColumn) + && (sOtherRaiderP->nColumn != 0) + && (sRaiderP->nRow != sOtherRaiderP->nRow)) + { + sRaiderP->nColumn = 0; + } + } else { + if ((!sRaiderP->bRightColumn) + && (sOtherRaiderP->nColumn != 2) + && (sRaiderP->nRow != sOtherRaiderP->nRow)) + { + sRaiderP->nColumn = 2; + } + } + break; + case 2: + sRaiderP->bRightColumn = TRUE; + if ((!sRaiderP->bMidColumn) + && (sOtherRaiderP->nColumn != 1) + && (sRaiderP->nRow != sOtherRaiderP->nRow)) + { + sRaiderP->nColumn = 1; + } + break; + } + } + } + } + } + } + + // enable/disable raiders sound + if ((sRaiderA.bAttacking && (sRaiderA.nRow >= 0) && (sRaiderA.nRow < SPACEALERT_BLIP_ROWS)) + || (sRaiderB.bAttacking && (sRaiderB.nRow >= 0) && (sRaiderB.nRow < SPACEALERT_BLIP_ROWS))){ + SpaceAlert_PlayRaiderSound(); + } else { + SpaceAlert_StopRaiderSound(); + } + +} + +void DoHitTest() +{ + if (nCurrentMissileRow < 0) + { + // missile is off screen + return; + } + + for (int i=0; i<2; i++){ + RAIDER *sRaiderP = i ? &sRaiderB : &sRaiderA; + if (sRaiderP->bAttacking){ + if (((nCurrentMissileRow) == sRaiderP->nRow) + && (nColumnSelector == sRaiderP->nColumn)){ + + if ((nCurrentMissileRow == (SPACEALERT_BLIP_ROWS-1)) + && (nColumnSelector == 1)){ + // don't count 0 point hits to center column if not fired + } else { + + // hit a raider + sRaiderP->bAttacking = FALSE; + UpdateBlips(); + + // draw the blips field (minus the score) + { + SpaceAlert_ClearScreen(); + Platform_StartDraw(); + + for (int y = 0; y < SPACEALERT_BLIP_ROWS; y++){ + for (int x = 0; x < SPACEALERT_BLIP_COLUMNS; x++){ + SpaceAlert_DrawBlip(Blips[x][y], x, y); + } + } + + Platform_EndDraw(); + } + + + SpaceAlert_PlaySound(SPACEALERT_SOUND_HIT, PLAYSOUNDFLAGS_PRIORITY); + + // add the score + nPoints += (SPACEALERT_BLIP_ROWS-1) - nCurrentMissileRow; + + // recharge the missile + nCurrentMissileRow = SPACEALERT_BLIP_ROWS - 1; + + --nRaiderCount; + + if (nRaiderCount <= 0){ + // no more raiders -- win + // draw a blank screen during the tune + sRaiderA.bAttacking = FALSE; + sRaiderB.bAttacking = FALSE; + nCurrentMissileRow = -1; + SpaceAlert_ClearScreen(); + SpaceAlert_StopRaiderSound(); + SpaceAlert_PlaySound(SPACEALERT_SOUND_WIN, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + bWin = TRUE; + return; + } else { + // set up next wave + nTimerAttackWave = TIME_ATTACKWAVE - ((Platform_Random(4) == 0) ? (TIME_ATTACKWAVE / 2) : 0); + } + + + } + + } + } + } +} + + +void UpdateBlips() +{ + // draw the raider blips + for (int i=0; i<2; i++){ + RAIDER *sRaiderP = i ? &sRaiderB : &sRaiderA; + if (sRaiderP->bAttacking){ + if ((sRaiderP->nColumn >= 0) && (sRaiderP->nColumn < SPACEALERT_BLIP_COLUMNS) + && (sRaiderP->nRow >= 0) && (sRaiderP->nRow < SPACEALERT_BLIP_ROWS)){ + Blips[sRaiderP->nColumn][sRaiderP->nRow] = BLIP_DIM; + } + } + } + + // draw the player missile blip + if ((nCurrentMissileRow <= (SPACEALERT_BLIP_ROWS - 1)) + && (nCurrentMissileRow >= 0)){ + Blips[nColumnSelector][nCurrentMissileRow] = BLIP_BRIGHT; + } + +} + +void PaintGame() +{ + Platform_StartDraw(); + + // draw the blips field + for (int y = 0; y < SPACEALERT_BLIP_ROWS; y++){ + for (int x = 0; x < SPACEALERT_BLIP_COLUMNS; x++){ + SpaceAlert_DrawBlip(Blips[x][y], x, y); + } + } + + // draw the score + if (bPower){ + SpaceAlert_DrawScore(nPoints); + } + + Platform_EndDraw(); +} + + +void InitAttack() +{ + sRaiderA.nRow = -2; + sRaiderA.nSlow = Platform_Random(3); + sRaiderA.nColumn = Platform_Random(3); + sRaiderA.bAttacking = TRUE; + sRaiderA.bLeftColumn = FALSE; + sRaiderA.bMidColumn = FALSE; + sRaiderA.bRightColumn = FALSE; + + if ((Platform_Random(2) == 0) && (nRaiderCount > 1)){ + + // dual attack + + if (Platform_Random(3) == 0){ + // stagger the attack + sRaiderB.nRow = -(Platform_Random(5) + 2); + sRaiderB.nSlow = 1; + } else { + // attack in parallel + sRaiderB.nRow = -2; + sRaiderB.nSlow = Platform_Random(3); + } + + // make sure the raiders don't start on the same column + do { + sRaiderB.nColumn = Platform_Random(3); + } while (sRaiderB.nColumn == sRaiderA.nColumn); + + sRaiderB.bAttacking = TRUE; + sRaiderB.bLeftColumn = FALSE; + sRaiderB.bMidColumn = FALSE; + sRaiderB.bRightColumn = FALSE; + } +} + diff --git a/source/game/SpaceAlert.h b/source/game/SpaceAlert.h new file mode 100644 index 0000000..2d27cb7 --- /dev/null +++ b/source/game/SpaceAlert.h @@ -0,0 +1,64 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __SPACEALERT_H__ +#define __SPACEALERT_H__ + +#include "Platform.h" +#include "Platform_Spacealert.h" + + +#define SPACEALERT_BLIP_ROWS 7 +#define SPACEALERT_BLIP_COLUMNS 3 + +#define SPACEALERT_SOUND_FIRE 0 +#define SPACEALERT_SOUND_HIT 1 +#define SPACEALERT_SOUND_LOSE 2 +#define SPACEALERT_SOUND_WIN 3 +#define SPACEALERT_SOUND_RAIDER 4 + +void SpaceAlert_Run(); +void SpaceAlert_PowerOn(); +void SpaceAlert_PowerOff(); +BOOL SpaceAlert_GetPower(); + + +#endif + + + + + diff --git a/source/game/SubChase.c b/source/game/SubChase.c new file mode 100644 index 0000000..c88c5a1 --- /dev/null +++ b/source/game/SubChase.c @@ -0,0 +1,586 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#include "SubChase.h" +#include "Games.h" + + +// constants + +typedef int BLIP; +static BLIP Blips[SUBCHASE_BLIP_COLUMNS][SUBCHASE_BLIP_ROWS]; + +#define TIME_SONAR_SLOW 5 +#define TIME_SONAR_FAST 2 +#define TIME_ENEMY_SUB_MOVE 30 +#define TIME_INITIAL_FIRE_TORPEDO_DELAY 250 +#define TIME_FIRE_TORPEDO_DELAY 20 +#define TIME_TORPEDO_MOVE 6 +#define TIME_KILL_GAME_TIMER 80 + +// game variables +static BOOL bGameOver; +static BOOL bInFrame = FALSE; +static BOOL bPower; + +static int nScore; +static int nCharges; +static int nChargeValue; + +static int nTimerSonar; +static int nTimerEnemySubMove; +static int nTimerFireTorpedo; +static int nTimerMoveTorpedo; +static int nKillGameTimer; + +static int nSubDirX; +static int nTorpedoDirX; + +static BOOL bPlayerHasMoved; + +static BOOL bInitialTorpedoFired = FALSE; + +static void InitGame(); +static void PositionEnemySub(); +static void FireTorpedoes(); +static void DrawBlips(); +static void DrawScore(int nDisplay); + +typedef struct OBJECT +{ + int x; + int y; + BOOL bEnable; +}OBJECT; + +static OBJECT player; +static OBJECT sub; +static OBJECT torpedo[2]; + + +BOOL SubChase_GetPower() +{ + return (bPower ? TRUE : FALSE); +} + +void SubChase_PowerOn() +{ + InitGame(); + bPower = TRUE; +} + +void SubChase_PowerOff() +{ + bPower = FALSE; +} + +int SubChase_GetSkill() +{ + return 0; +} + +void SubChase_SetSkill(int i) +{ +} + +void InitGame() +{ + bGameOver = FALSE; + + nScore = 0; + nCharges = 30; + nChargeValue = 5; + + player.x = 3; + player.y = 1; + + torpedo[0].bEnable = FALSE; + torpedo[1].bEnable = FALSE; + + nTorpedoDirX = 1; + nTimerFireTorpedo = TIME_INITIAL_FIRE_TORPEDO_DELAY; + nKillGameTimer = TIME_KILL_GAME_TIMER; + + bPlayerHasMoved = FALSE; + + nTimerSonar = 0; + + PositionEnemySub(); + + Platform_IsNewSecond(); +} + + +void SubChase_Run(int tu) +{ + int x, y; + + // prevent reentrancy + if (bInFrame){ return; } + bInFrame = TRUE; + + // init the blips field + for (y = 0; y < SUBCHASE_BLIP_ROWS; y++){ + for (x = 0; x < SUBCHASE_BLIP_COLUMNS; x++){ + Blips[x][y] = BLIP_OFF; + } + } + + // handle power off, and game over states + if (bPower){ + if (bGameOver) + { + Blips[player.x][player.y] = BLIP_BRIGHT; + DrawBlips(); + DrawScore(nScore); + bInFrame = FALSE; + return; + } + } else { + SubChase_ClearScreen(); + DrawScore(-1); + bInFrame = FALSE; + return; + } + + // run the game + + BOOL bHit = FALSE; + + BOOL bChange; + if (SubChase_GetInputLEFT(&bChange)) + { + bPlayerHasMoved = TRUE; + if (bChange) + { + // move left + if (player.x > 0) + { + player.x--; + } + } + } + else if (SubChase_GetInputRIGHT(&bChange)) + { + bPlayerHasMoved = TRUE; + if (bChange) + { + // move right + if (player.x < (SUBCHASE_BLIP_COLUMNS-1)) + { + player.x++; + } + } + } + else if (SubChase_GetInputUP(&bChange)) + { + bPlayerHasMoved = TRUE; + if (bChange) + { + // move up + if (player.y > 0) + { + player.y--; + } + } + } + else if (SubChase_GetInputDOWN(&bChange)) + { + bPlayerHasMoved = TRUE; + if (bChange) + { + // move down + if (player.y < (SUBCHASE_BLIP_ROWS-1)) + { + player.y++; + } + } + } + + if (SubChase_GetInputFIRE(NULL)) + { + // release depth charge - check for hit + if ((player.x == sub.x) && (player.y == sub.y)) + { + // hit + { + // clear the screen except for the player's ship + SubChase_ClearScreen(); + DrawScore(-1); + Platform_StartDraw(); + SubChase_DrawBlip(BLIP_BRIGHT, player.x, player.y); + Platform_EndDraw(); + } + SubChase_PlaySound(SUBCHASE_SOUND_HIT, PLAYSOUNDFLAGS_PRIORITY); + nScore+=nChargeValue; + nChargeValue = 5; + bInitialTorpedoFired = TRUE; + PositionEnemySub(); + } + else + { + // miss + { + // clear the screen except for the player's ship + SubChase_ClearScreen(); + DrawScore(-1); + Platform_StartDraw(); + SubChase_DrawBlip(BLIP_BRIGHT, player.x, player.y); + Platform_EndDraw(); + } + SubChase_PlaySound(SUBCHASE_SOUND_CHARGE, PLAYSOUNDFLAGS_PRIORITY); + nTimerEnemySubMove = 0; + + // decrease charge value + if (nChargeValue==5) + { + nChargeValue=3; + } + else if (nChargeValue==3) + { + nChargeValue=2; + } + else if (nChargeValue==2) + { + nChargeValue=1; + } + + // decrease number of charges and check for game over + --nCharges; + if (nCharges == 0) + { + // GAME OVER! + { + // clear the screen except for the player's ship + SubChase_ClearScreen(); + DrawScore(-1); + Platform_StartDraw(); + SubChase_DrawBlip(BLIP_BRIGHT, player.x, player.y); + Platform_EndDraw(); + } + SubChase_PlaySound(SUBCHASE_SOUND_SINK, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + bInFrame = FALSE; + return; + } + } + } + + // check for proximity to enemy sub + int nSonar = 0; + if (((sub.x == player.x) && (sub.y == player.y)) + || ((sub.x == player.x) && (sub.y == player.y-1)) + || ((sub.x == player.x) && (sub.y == player.y+1))) + { + // fast + nSonar = 1; + } + else if (((sub.x == player.x-1) && (sub.y == player.y-1)) + || ((sub.x == player.x-1) && (sub.y == player.y)) + || ((sub.x == player.x-1) && (sub.y == player.y+1)) + || ((sub.x == player.x+1) && (sub.y == player.y-1)) + || ((sub.x == player.x+1) && (sub.y == player.y)) + || ((sub.x == player.x+1) && (sub.y == player.y+1))) + { + // slow + nSonar = 2; + } + + if (nSonar) + { + ++nTimerSonar; + if (nSonar==2) + { + if (nTimerSonar > TIME_SONAR_SLOW) + { + SubChase_PlaySound(SUBCHASE_SOUND_SONAR, PLAYSOUNDFLAGS_ASYNC); + nTimerSonar = 0; + } + } + else + { + if (nTimerSonar > TIME_SONAR_FAST) + { + SubChase_PlaySound(SUBCHASE_SOUND_SONAR, PLAYSOUNDFLAGS_ASYNC); + nTimerSonar = 0; + } + } + } + else + { + nTimerSonar = 0; + } + + // update the blips + Blips[player.x][player.y] = BLIP_BRIGHT; +// Blips[sub.x][sub.y] = BLIP_DIM; + if (torpedo[0].bEnable) + { + if ((torpedo[0].x >= 0) && (torpedo[0].x < SUBCHASE_BLIP_COLUMNS)) + { + Blips[torpedo[0].x][torpedo[0].y] = BLIP_DIM; + } + } + if (torpedo[1].bEnable) + { + if ((torpedo[1].x >= 0) && (torpedo[1].x < SUBCHASE_BLIP_COLUMNS)) + { + Blips[torpedo[1].x][torpedo[1].y] = BLIP_DIM; + } + } + + // check for torpedo hit + if (((torpedo[0].bEnable) && (torpedo[0].x == player.x) && (torpedo[0].y == player.y)) + || ((torpedo[0].bEnable) && (torpedo[0].x == player.x) && (torpedo[0].y == player.y))) + { + // torpedo hit + { + // clear the screen except for the player's ship + SubChase_ClearScreen(); + DrawScore(-1); + Platform_StartDraw(); + SubChase_DrawBlip(BLIP_BRIGHT, player.x, player.y); + Platform_EndDraw(); + } + SubChase_PlaySound(SUBCHASE_SOUND_SINK, PLAYSOUNDFLAGS_PRIORITY); + bGameOver = TRUE; + bInFrame = FALSE; + return; + } + + DrawBlips(); + DrawScore(nScore); + + // move the enemy sub + --nTimerEnemySubMove; + if (nTimerEnemySubMove <= 0) + { + nTimerEnemySubMove = TIME_ENEMY_SUB_MOVE; + if (nSubDirX > 0) + { + if (sub.x >= (SUBCHASE_BLIP_COLUMNS-1)) + { + nSubDirX = -1; + } + } + else + { + if (sub.x <= 0) + { + nSubDirX = 1; + } + } + sub.x += nSubDirX; + } + + // move the torpedoes + --nTimerMoveTorpedo; + if (nTimerMoveTorpedo <= 0) + { + nTimerMoveTorpedo = TIME_TORPEDO_MOVE; + for (int i=0; i<2; i++) + { + if (torpedo[i].bEnable) + { + torpedo[i].x += nTorpedoDirX; + if ((torpedo[i].x < 0) && (nTorpedoDirX < 0)) + { + torpedo[i].bEnable = FALSE; + } + if ((torpedo[i].x >= SUBCHASE_BLIP_COLUMNS) && (nTorpedoDirX > 0)) + { + torpedo[i].bEnable = FALSE; + } + } + } + } + + if (nKillGameTimer > 0) + { + --nKillGameTimer; + } + if (!bPlayerHasMoved && (nKillGameTimer <= 0)) + { + // player is just sitting there + // fire a torpedo at him right now + // (as per real game) + FireTorpedoes(); + bPlayerHasMoved = TRUE; + } + + // randomly fire torpedoes as required + if ((torpedo[0].bEnable == FALSE) && (torpedo[1].bEnable == FALSE)) + { + if (nTimerFireTorpedo > 0) + { + --nTimerFireTorpedo; + } + if (Platform_Random(5) == 0) + { + if (nTimerFireTorpedo <= 0) + { + FireTorpedoes(); + } + } + } + + bInFrame = FALSE; +} + +void DrawBlips() +{ + Platform_StartDraw(); + + // draw the blips field + for (int y = 0; y < SUBCHASE_BLIP_ROWS; y++){ + for (int x = 0; x < SUBCHASE_BLIP_COLUMNS; x++) + { + switch(Blips[x][y]){ + case BLIP_OFF: + case BLIP_DIM: + case BLIP_BRIGHT: + SubChase_DrawBlip(Blips[x][y], x, y); + break; + } + } + } + + Platform_EndDraw(); +} + +void DrawScore(int nDisplay) +{ + // draw the display + Platform_StartDraw(); + SubChase_DrawScore(nDisplay); + Platform_EndDraw(); +} + +void PositionEnemySub() +{ + nTimerEnemySubMove = TIME_ENEMY_SUB_MOVE; + nSubDirX = Platform_Random(2) ? 1 : -1; + + while (1) + { + sub.x = Platform_Random(SUBCHASE_BLIP_COLUMNS); + sub.y = Platform_Random(SUBCHASE_BLIP_ROWS); + if (((sub.x == player.x) && (sub.y == player.y)) + || ((sub.x == player.x-1) && (sub.y == player.y-1)) + || ((sub.x == player.x-1) && (sub.y == player.y)) + || ((sub.x == player.x-1) && (sub.y == player.y+1)) + || ((sub.x == player.x+1) && (sub.y == player.y-1)) + || ((sub.x == player.x+1) && (sub.y == player.y)) + || ((sub.x == player.x+1) && (sub.y == player.y+1)) + || ((sub.x == player.x) && (sub.y == player.y-1)) + || ((sub.x == player.x) && (sub.y == player.y+1))) + { + // try again + } + else + { + return; + } + } +} + +static void FireTorpedoes() +{ + nTimerFireTorpedo = TIME_FIRE_TORPEDO_DELAY; + nTimerMoveTorpedo = TIME_TORPEDO_MOVE; + + // enable 1 or more torpedoes + torpedo[0].bEnable = TRUE; + if (bInitialTorpedoFired) + { + torpedo[1].bEnable = Platform_Random(7) ? FALSE : TRUE; + } + + // pick the direction based on where the player is + if (player.x < 3) + { + nTorpedoDirX = -1; + } + else if (player.x > 3) + { + nTorpedoDirX = 1; + } + else + { + if (!bPlayerHasMoved) + { + // when player hasn't moved, the torpedo is always from the right + nTorpedoDirX = -1; + } + else + { + nTorpedoDirX = (Platform_Random(2)) ? 1 : -1; + } + } + + if (nTorpedoDirX > 0) + { + if ((player.x == (SUBCHASE_BLIP_COLUMNS-1)) && Platform_Random(2)) + { + torpedo[0].x = 3; + torpedo[1].x = 3; + } + else + { + torpedo[0].x = player.x - Platform_Random(5) - 3; + torpedo[1].x = player.x - Platform_Random(5) - 3; + } + } + else + { + if ((player.x == 0) && Platform_Random(2)) + { + torpedo[0].x = 3; + torpedo[1].x = 3; + } + else + { + torpedo[0].x = player.x + Platform_Random(5) + 3; + torpedo[1].x = player.x + Platform_Random(5) + 3; + } + } + + torpedo[0].y = player.y; + torpedo[1].y = Platform_Random(3); + + bInitialTorpedoFired = TRUE; +} + diff --git a/source/game/SubChase.h b/source/game/SubChase.h new file mode 100644 index 0000000..66ceaf0 --- /dev/null +++ b/source/game/SubChase.h @@ -0,0 +1,64 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __SUBCHASE_H__ +#define __SUBCHASE_H__ + +#include "Platform.h" +#include "Platform_subchase.h" + + +#define SUBCHASE_BLIP_ROWS 3 +#define SUBCHASE_BLIP_COLUMNS 7 + +#define SUBCHASE_SOUND_SONAR 0 +#define SUBCHASE_SOUND_CHARGE 1 +#define SUBCHASE_SOUND_HIT 2 +#define SUBCHASE_SOUND_SINK 3 + +void SubChase_Run(); +void SubChase_SetSkill(int i); +int SubChase_GetSkill(); +void SubChase_PowerOn(); +void SubChase_PowerOff(); +BOOL SubChase_GetPower(); + + +#endif + + + + + diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..e451d8c --- /dev/null +++ b/source/main.c @@ -0,0 +1,247 @@ +/* + * LEDhead for Wii + * Copyright (C) 2017-2020 Nebiun + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "LED_Handled.h" +#include "Games.h" +#include "Platform.h" +#include "cover_png.h" +#include "grrlib_logo_png.h" +#include "WKRD_png.h" +#include "WKLU_png.h" + +//#define CHECK_PAINTTIME 1 +//#define PRINT_TRACE 1 + +#ifdef CHECK_PAINTTIME +struct timeval tv1, tv2; +long delta_usec, max_delta; +#endif + +int trace = 0; +static int elapsed = 0; + +static void timerProc(syswd_t alarm, void *arg) +{ + if (gCurrentGame) + { + elapsed++; + // set up the next timer event + struct timespec clock_time; + + clock_time.tv_sec = 0; + clock_time.tv_nsec = gCurrentGame->tu * 1000000; + SYS_SetAlarm(alarm,&clock_time,timerProc, NULL); + } +} + +int main(int argc, char **argv) +{ + GRRLIB_texImg *background; + GRRLIB_texImg *game_screen = NULL; + GRRLIB_texImg *pre_screen = NULL; + GRRLIB_texImg *post_screen = NULL; + GRRLIB_texImg *next, *prev; + GRRLIB_texImg *logo; + u16 btn, last_btn = -1; + int help_on = 0; + + GRRLIB_Init(); + WPAD_Init(); + //set IR resolution to 640 width and 480 height + WPAD_SetVRes(WPAD_CHAN_ALL, 640, 480); + //return data for wii remotes should contain Button Data, Accelerometer, and IR + WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR); + + // Audio + ASND_Init(); + ASND_Pause(0); + + background = GRRLIB_LoadTexture(cover_png); + next = GRRLIB_LoadTexture(WKRD_png); + prev = GRRLIB_LoadTexture(WKLU_png); + Platform_Init(); + + GRRLIB_FillScreen(RGBA(0x80,0x00,0x00,0xff)); + logo = GRRLIB_LoadTexture(grrlib_logo_png); + GRRLIB_DrawImg((rmode->viWidth - logo->w)/2,(rmode->viHeight - logo->h)/2,logo,0,1,1, 0xFFFFFFFF); + GRRLIB_Render(); + sleep(1); + GRRLIB_FreeTexture(logo); + + GRRLIB_FillScreen(RGBA(0x00,0x00,0x00,0x00)); // black; + GRRLIB_DrawImg(0,0,background,0,1,1, 0xFFFFFFFF); + GRRLIB_Render(); + sleep(2); + + // Loop forever + while(1) { + int changed; + + WPAD_ScanPads(); + + changed = 0; + btn = WPAD_ButtonsHeld(0); + + if(last_btn == -1 || btn != last_btn) { + last_btn = btn; + + if(btn & WPAD_BUTTON_A) { + if(gCurrentGame == NULL) { + gCurrentGame = &gGameContext[0]; + changed++; + } + else if(gCurrentGame->Init != NULL) { + usleep(200000); + /* play */ + gCurrentGame->Init(); + + // set up the next timer event + struct timespec clock_time; + syswd_t timer; + + SYS_CreateAlarm(&timer); + clock_time.tv_sec = 0; + clock_time.tv_nsec = gCurrentGame->tu * 1000000; + SYS_SetAlarm(timer,&clock_time,timerProc, NULL); + + while(1) { + if(elapsed) { + elapsed = 0; + Platform_Input(); + if(Platform_CloseGame()) { + break; + } +#ifdef CHECK_PAINTTIME + gettimeofday(&tv1,NULL); +#endif + gCurrentGame->Run(gCurrentGame->tu); +#ifdef CHECK_PAINTTIME + gettimeofday(&tv2,NULL); + delta_usec = tv2.tv_sec - tv1.tv_sec; + delta_usec = 1000000 * delta_usec + tv2.tv_usec - tv1.tv_usec; + if(delta_usec > max_delta) + max_delta = delta_usec; + + debugPrintf(300, 60, 0xFFFFFFFF, "run us=%d (max %d)", delta_usec, max_delta); +#endif +#ifdef PRINT_TRACE + debugPrintf(300, 30, 0xFFFFFFFF, "trc=%d", trace); +#endif + } +#ifdef CHECK_PAINTTIME + gettimeofday(&tv1,NULL); +#endif + gCurrentGame->Paint(); +#ifdef CHECK_PAINTTIME + gettimeofday(&tv2,NULL); + delta_usec = tv2.tv_sec - tv1.tv_sec; + delta_usec = 1000000 * delta_usec + tv2.tv_usec - tv1.tv_usec; + + debugPrintf(300, 90, 0xFFFFFFFF, "paint us=%d", delta_usec); +#endif + if(Platform_SoundIsOff()) + print_text(realx(0), realy(game_screen->h + 30), 0xFFFFFFFF, "(mute)"); + else { + Platform_KeyShow(realx(0), realy(game_screen->h + 30), WK_A); + print_text(realx(0 + 30), realy(game_screen->h + 30), 0xFFFFFFFF, "for mute"); + } + Platform_KeyShow(realx(0), realy(game_screen->h + 60), WK_HOME); + print_text(realx(0 + 30), realy(game_screen->h + 60), 0xFFFFFFFF, "exit game"); + GRRLIB_Render(); + } + gCurrentGame->DeInit(); + SYS_CancelAlarm(timer); + usleep(500000); + } + + } + else if(((btn & WPAD_BUTTON_LEFT) || (btn & WPAD_BUTTON_DOWN))&& (gCurrentGame != NULL)) { + if(gCurrentGame < &gGameContext[NUM_GAMES-1]) { + gCurrentGame++; + changed++; + } + } + else if(((btn & WPAD_BUTTON_RIGHT) || (btn & WPAD_BUTTON_UP)) && (gCurrentGame != NULL)) { + if(gCurrentGame > &gGameContext[0]) { + gCurrentGame--; + changed++; + } + } + else if(btn & WPAD_BUTTON_B) { + help_on = 1 - help_on; + usleep(300000); + } + else if(btn & WPAD_BUTTON_HOME) { + break; + } + } + + if(gCurrentGame == NULL) { + GRRLIB_DrawImg(0,0,background,0,1,1, 0xFFFFFFFF); + print_text(215, 430, 0xFFFFFFFF, "Press to continue"); + Platform_KeyShow(284, 430, WK_A); + } + else { + if(changed) { + if(game_screen != NULL) + GRRLIB_FreeTexture(game_screen); + if(pre_screen != NULL) { + GRRLIB_FreeTexture(post_screen); + post_screen = NULL; + } + if(pre_screen != NULL) { + GRRLIB_FreeTexture(pre_screen); + pre_screen = NULL; + } + game_screen = GRRLIB_LoadTexture(gCurrentGame->screen); + if(gCurrentGame > &gGameContext[0]) + post_screen = GRRLIB_LoadTexture((gCurrentGame-1)->screen); + if(gCurrentGame < &gGameContext[NUM_GAMES-1]) + pre_screen = GRRLIB_LoadTexture((gCurrentGame+1)->screen); + } + /* x e y vanno ricalcolate per posizionare lo screen */ + GRRLIB_DrawImg(realx(0),realy(0),game_screen,0,1,1, 0xFFFFFFFF); + print_text(realx(0), realy(game_screen->h + 20), 0xFFFFFFFF, "%s", gCurrentGame->szName); + if(post_screen != NULL) { + GRRLIB_DrawImg(realx(0)-(post_screen->w/2)-50,realy(0)+50,post_screen,0,0.5,0.5, 0xFFFFFFFF); + GRRLIB_DrawImg(realx(0)-(prev->w/2)-15,realy(0)+125,prev,0,0.5,0.5, 0xFFFFFFFF); + } + if(pre_screen != NULL) { + GRRLIB_DrawImg(realx(0)+game_screen->w+15,realy(0)+125,next,0,0.5,0.5, 0xFFFFFFFF); + GRRLIB_DrawImg(realx(0)+game_screen->w+50,realy(0)+50,pre_screen,0,0.5,0.5, 0xFFFFFFFF); + } + Platform_KeyShow(realx(0), realy(game_screen->h + 60), WK_A); + print_text(realx(0 + 30), realy(game_screen->h + 60), 0xFFFFFFFF, "to start the game"); + Platform_KeyShow(realx(0), realy(game_screen->h + 90), WK_B); + print_text(realx(0 + 30), realy(game_screen->h + 90), 0xFFFFFFFF, "for keys map"); + if(help_on == 1 && gCurrentGame->Help != NULL) + gCurrentGame->Help(); +#ifdef PRINT_TRACE + debugPrintf(300, 30, 0xFFFFFFFF, "trc=%d",trace); +#endif + } + GRRLIB_Render(); + } + + ASND_End(); + +// Debug_destroy(); + GRRLIB_Exit(); + + exit(0); // Use exit() to exit a program, do not use 'return' from main() +} diff --git a/source/platform/Platform.c b/source/platform/Platform.c new file mode 100644 index 0000000..89dd6a0 --- /dev/null +++ b/source/platform/Platform.c @@ -0,0 +1,307 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include +#include "asndlib.h" +#include "Platform.h" +#include "Random.h" + +static int bMute = 0; + +////////////////////////////////////////////////////// +// OS dependant support +////////////////////////////////////////////////////// +void Platform_Init() +{ + // init the random number generator + InitRandom(); +} + +void Platform_DeInit() +{ + Platform_EndDraw(); + + // kill the random number generator + DeinitRandom(); +} + +void Platform_StartDraw() +{ + +} + +void Platform_EndDraw() +{ + +} + +int Platform_SoundIsOff() +{ + return bMute ? 1 : 0; +} + +int Platform_Random(int nRange) +{ + return (Random(nRange)); +} + +BOOL Platform_IsNewSecond() +{ + static time_t lastsec = -1; + + time_t newsec = time(NULL); + + if (newsec != lastsec){ + lastsec = newsec; + return TRUE; + } + return FALSE; +} + +/* Pause for n millisecs */ +void Platform_Pause(int n) +{ + usleep(1000 * n); +} + +static Sound_t *loop = NULL; +void Platform_PlaySound(Sound_t *sound, unsigned int nFlags) +{ + if(bMute) { + if (!(nFlags & PLAYSOUNDFLAGS_ASYNC)) + usleep(1000 * sound->msec); + return; + } + + if (nFlags & PLAYSOUNDFLAGS_LOOP) + { + if (nFlags & PLAYSOUNDFLAGS_PRIORITY) + ASND_StopVoice(1); + + ASND_SetInfiniteVoice(1, VOICE_MONO_8BIT, 11025, 0, + (void *) sound->stream, sound->len, MAX_VOLUME, MAX_VOLUME); + loop = sound; + } + else { + if (nFlags & PLAYSOUNDFLAGS_PRIORITY) + ASND_StopVoice(0); + + ASND_SetVoice(0, VOICE_MONO_8BIT, 11025, 0, + (void *) sound->stream, sound->len, MAX_VOLUME, MAX_VOLUME, NULL); + if (!(nFlags & PLAYSOUNDFLAGS_ASYNC)) + while(ASND_StatusVoice(0) == SND_WORKING); + } +} + +void Platform_StopSound() +{ + if(loop != NULL) + ASND_StopVoice(1); + ASND_StopVoice(0); +} + +static u32 btn; +static int wpad = 0; + +void Platform_Input() +{ + static WPADData data; + WPADData *Data; + + WPAD_ScanPads(); + + Data = WPAD_Data(wpad); + data = *Data; + + btn = data.btns_h; +} + +int PlatformSetInput(int pad) +{ + u32 type; + + if(pad < 0 || pad > 1) + return -1; + + if(pad == wpad) + return 0; + + if(WPAD_Probe(pad, &type) == WPAD_ERR_NONE) { + WPAD_Rumble(pad, 1); + sleep(1); + WPAD_Rumble(pad, 0); + wpad = pad; + return 0; + } + + return -1; +} + +int PlatformGetInput() +{ + return wpad; +} + +BOOL Platform_GetInputUP() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_RIGHT); +} + +BOOL Platform_GetInputDOWN() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_LEFT); +} + +BOOL Platform_GetInputLEFT() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_UP); +} + +BOOL Platform_GetInputRIGHT() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_DOWN); +} + +BOOL Platform_GetInput2() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_2); +} + +BOOL Platform_GetInput1() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_1); +} + +BOOL Platform_GetInputPLUS() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_PLUS); +} + +BOOL Platform_GetInputMINUS() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_MINUS); +} + +BOOL Platform_GetInputMouseDown() +{ + if(btn & WPAD_BUTTON_B) + return 0; + return (btn & WPAD_BUTTON_A); +} + +int Platform_GetPowerSwitch(int type) +{ + static u32 last_btn = 0; + + if(btn != last_btn) { + last_btn = btn; + + if((btn & WPAD_BUTTON_A) == WPAD_BUTTON_A) { + bMute = 1 - bMute; + } + else if((btn & WPAD_BUTTON_B) == WPAD_BUTTON_B) { + switch(type) { + case ONOFF_1OFF2: + case ONOFF_OFF12: + if(btn & WPAD_BUTTON_UP) { + btn &= ~WPAD_BUTTON_UP; + return -1; + } + if(btn & WPAD_BUTTON_DOWN) { + btn &= ~WPAD_BUTTON_DOWN; + return 1; + } + break; + case ONOFF_SWITCH: + default: + if(btn & WPAD_BUTTON_LEFT) { + btn &= ~WPAD_BUTTON_LEFT; + return -1; + } + if(btn & WPAD_BUTTON_RIGHT) { + btn &= ~WPAD_BUTTON_RIGHT; + return 1; + } + break; + } + } + } + return 0; +} + +BOOL Platform_CloseGame() +{ + return (btn & WPAD_BUTTON_HOME); +} + +BOOL Platform_GetRealTimeInput1() +{ + Platform_Input(); + return Platform_GetInput1(); +} + +BOOL Platform_GetRealTimeInput2() +{ + Platform_Input(); + return Platform_GetInput2(); +} + +BOOL Platform_GetRealTimeInputPLUS() +{ + Platform_Input(); + return Platform_GetInputPLUS(); +} + +BOOL Platform_GetRealTimeInputMINUS() +{ + Platform_Input(); + return Platform_GetInputMINUS(); +} diff --git a/source/platform/Platform.h b/source/platform/Platform.h new file mode 100644 index 0000000..0748c55 --- /dev/null +++ b/source/platform/Platform.h @@ -0,0 +1,160 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ +#include +#include +#include "LED_Handled.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef BOOL +#define BOOL int +#endif + +// on-off switch types +#define ONOFF_1OFF2 1 +#define ONOFF_OFF12 2 +#define ONOFF_SWITCH 0 + +// common game defines +#define BLIP_OFF 0 +#define BLIP_DIM 1 +#define BLIP_BRIGHT 2 +#define BLIP_DIMBLINK 3 +#define BLIP_BRIGHTBLINK 4 +#define BLIP_DIMFLICKER 5 + +// xxx_PlaySound() flags +#define PLAYSOUNDFLAGS_PRIORITY 0x00001 +#define PLAYSOUNDFLAGS_LOOP 0x00002 +#define PLAYSOUNDFLAGS_ASYNC 0x00004 + +typedef enum { + WK_1, + WK_2, + WK_A, + WK_B, + WK_BUD, + WK_BLR, + WK_PLUS, + WK_MINUS, + WK_HOME, + WK_DPAD, + WK_LR, + WK_UD, + WK_NUMKEY +} wiikey_t ; + +typedef struct { + const void *stream; + int len; + int msec; +} Sound_t; + +typedef struct { + int x; + int y; + int status; +} Blip_t; + +typedef struct { + int x; + int y; + int val; +} Stat_t; + +typedef struct { + int x; + int y; + int val; + int type; +} Digit_t; + +typedef struct { + int x; + int y; +} Coord_t; + +typedef struct { + wiikey_t val; + Coord_t pos; +} Help_t; + +#define Sound_set(a, mp3, sz, ms) \ + { ((Sound_t *)a)->stream = mp3; ((Sound_t *)a)->len = sz; ((Sound_t *)a)->msec = ms; } + +// interface that the platform must provide to the games + +void Platform_Init(); +void Platform_Help(Help_t *vect, int n); +void Platform_KeyShow(int x, int y, int val); +void Platform_DeInit(); + +void Platform_StartDraw(); +void Platform_EndDraw(); +int Platform_Random(int nRange); +BOOL Platform_IsNewSecond(); +void Platform_Pause(int nMS); + +void Platform_PlaySound(Sound_t *sound, unsigned int nFlags); +void Platform_StopSound(); +int Platform_SoundIsOff(); + +void Platform_Input(); +int PlatformSetInput(int pad); +int PlatformGetInput(); + +BOOL Platform_GetInputUP(); +BOOL Platform_GetInputDOWN(); +BOOL Platform_GetInputLEFT(); +BOOL Platform_GetInputRIGHT(); +BOOL Platform_GetInput1(); +BOOL Platform_GetInput2(); +BOOL Platform_GetInputPLUS(); +BOOL Platform_GetInputMINUS(); + +BOOL Platform_GetRealTimeInput1(); +BOOL Platform_GetRealTimeInput2(); +BOOL Platform_GetRealTimeInputPLUS(); +BOOL Platform_GetRealTimeInputMINUS(); + +int Platform_GetPowerSwitch(int type); +BOOL Platform_CloseGame(); + +#endif diff --git a/source/platform/Platform_armorbattle.c b/source/platform/Platform_armorbattle.c new file mode 100644 index 0000000..3b512c3 --- /dev/null +++ b/source/platform/Platform_armorbattle.c @@ -0,0 +1,438 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "armorbattle.h" +#include "armorbattle_screen_png.h" +#include "armorbattle_blipdim_png.h" +#include "armorbattle_blipbright_png.h" +#include "armorbattle_digits_png.h" +#include "armorbattle_poweroff_png.h" +#include "armorbattle_poweron_png.h" +#include "armorbattle_tick_raw.h" +#include "armorbattle_near_raw.h" +#include "armorbattle_enemy_raw.h" +#include "armorbattle_fire_raw.h" +#include "armorbattle_hit_raw.h" +#include "armorbattle_score_raw.h" +#include "armorbattle_endgame_raw.h" + +#define DIGIT_W 24 +#define DIGIT_H 32 + +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpBlipDim; +static GRRLIB_texImg *bmpBlipBright; +static GRRLIB_texImg *bmpDigits; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpPowerOn; + +static BOOL bMineSound = FALSE; +static BOOL bMineSoundPlaying = FALSE; + +static Sound_t tcWaveRes[7]; +static Blip_t blip[ARMORBATTLE_BLIP_COLUMNS][ARMORBATTLE_BLIP_ROWS]; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, {1, 131} }, + { WK_BUD, {74, 232} }, + { WK_DPAD, { 147, 247} } +}; +//---------------------------------------------------------------------------- +// +// +void ArmorBattle_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void ArmorBattle_Init() +{ + int x, y; + + // Init sounds + Sound_set(&tcWaveRes[0], armorbattle_tick_raw, armorbattle_tick_raw_size, 17 ); + Sound_set(&tcWaveRes[1], armorbattle_near_raw, armorbattle_near_raw_size, 165 ); + Sound_set(&tcWaveRes[2], armorbattle_enemy_raw, armorbattle_enemy_raw_size, 124 ); + Sound_set(&tcWaveRes[3], armorbattle_fire_raw, armorbattle_fire_raw_size, 660 ); + Sound_set(&tcWaveRes[4], armorbattle_hit_raw, armorbattle_hit_raw_size, 524 ); + Sound_set(&tcWaveRes[5], armorbattle_score_raw, armorbattle_score_raw_size, 1542 ); + Sound_set(&tcWaveRes[6], armorbattle_endgame_raw, armorbattle_endgame_raw_size, 5244 ); + + // load images + bmpScreen = GRRLIB_LoadTexture(armorbattle_screen_png); + bmpDigits = GRRLIB_LoadTexture(armorbattle_digits_png); + GRRLIB_InitTileSet(bmpDigits, DIGIT_W, DIGIT_H, 0); + bmpPowerOff = GRRLIB_LoadTexture(armorbattle_poweroff_png); + bmpPowerOn = GRRLIB_LoadTexture(armorbattle_poweron_png); + bmpBlipDim = GRRLIB_LoadTexture(armorbattle_blipdim_png); + bmpBlipBright = GRRLIB_LoadTexture(armorbattle_blipbright_png); + + // grab some other values from the skin file + for (y = 0; y < ARMORBATTLE_BLIP_ROWS; y++){ + for (x = 0; x < ARMORBATTLE_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + pblip->x = (int)((x * ((float)armorbattle_blip_xspacing/100)) + armorbattle_blip_x); + pblip->y = (int)((y * ((float)armorbattle_blip_yspacing/100)) + armorbattle_blip_y); + pblip->status = -1; + } + } + + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = armorbattle_digit_x + x * armorbattle_digit_spacing; + digit[x].y = armorbattle_digit_y; + } + + if (!bInited) + { + PlatformSetInput(0); + + // turn game on + ArmorBattle_PowerOn(); + + bInited = TRUE; + } +} + +void ArmorBattle_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + bMineSoundPlaying = FALSE; + + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpBlipDim); + GRRLIB_FreeTexture(bmpBlipBright); + GRRLIB_FreeTexture(bmpDigits); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPowerOn); + + bInited = FALSE; +} + +void ArmorBattle_Paint() +{ + int x, y; + BOOL power = ArmorBattle_GetPower(); + int p_switch; + + p_switch = Platform_GetPowerSwitch(ONOFF_SWITCH); + if(p_switch == -1 && power == TRUE) { + ArmorBattle_PowerOff(); + } + if(p_switch == 1 && power == FALSE) { + ArmorBattle_PowerOn(); + } + + GRRLIB_DrawImg (realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power) + { + GRRLIB_DrawImg(realx(armorbattle_power_x), realy(armorbattle_power_y), bmpPowerOn, 0, 1, 1, 0xFFFFFFFF); + + // show blips + for (y = 0; y < ARMORBATTLE_BLIP_ROWS; y++){ + for (x = 0; x < ARMORBATTLE_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + switch(pblip->status) { + case BLIP_OFF: + break; + case BLIP_DIM: + GRRLIB_DrawImg (realx(pblip->x), realy(pblip->y), bmpBlipDim, 0, 1, 1, 0xFFFFFFFF); + break; + case BLIP_BRIGHT: + GRRLIB_DrawImg (realx(pblip->x), realy(pblip->y), bmpBlipBright, 0, 1, 1, 0xFFFFFFFF); + break; + } + } + } + + // Show time + for(x = 0; x < sizeof(digit)/sizeof(*digit); x++) { + if(digit[x].val == -1) + GRRLIB_DrawTile(realx(digit[x].x), realy(digit[x].y), bmpDigits, 0, 1, 1, 0xFFFFFFFF, 0); + else + GRRLIB_DrawTile(realx(digit[x].x), realy(digit[x].y), bmpDigits, 0, 1, 1, 0xFFFFFFFF, digit[x].val); + } + } + else + { + GRRLIB_DrawImg(realx(armorbattle_power_x), realy(armorbattle_power_y), bmpPowerOff, 0, 1, 1, 0xFFFFFFFF); + } + + +} + +void ArmorBattle_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < ARMORBATTLE_BLIP_ROWS; y++){ + for (int x = 0; x < ARMORBATTLE_BLIP_COLUMNS; x++){ + ArmorBattle_DrawBlip(BLIP_OFF, x, y); + } + } + + // erase the score display + ArmorBattle_DrawTime(-1); + + Platform_EndDraw(); +} + +void ArmorBattle_PlaySound(int nSound, unsigned int nFlags) +{ + if (bMineSoundPlaying && !(nFlags & PLAYSOUNDFLAGS_PRIORITY)) + { + // go away + return; + } + + if ((nFlags & PLAYSOUNDFLAGS_PRIORITY) || bMineSoundPlaying) + { + // stop any playing sounds first + Platform_StopSound(); + } + + // this sound will cut off any looping sounds + // note this so we can restart them later + bMineSoundPlaying = FALSE; + + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void ArmorBattle_StopSound() +{ + bMineSoundPlaying = FALSE; + bMineSound = FALSE; + + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +static void StartMineSound() +{ + if (!bMineSoundPlaying) + { + Platform_PlaySound(&tcWaveRes[ARMORBATTLE_SOUND_NEAR ], PLAYSOUNDFLAGS_LOOP | PLAYSOUNDFLAGS_ASYNC); + // mark the sound as playing + bMineSoundPlaying = TRUE; + } +} + +static void StopMineSound() +{ + if (bMineSoundPlaying) + { + Platform_StopSound(); + bMineSoundPlaying = FALSE; + } +} + +void ArmorBattle_PlayMineSound() +{ + if (!bMineSound) + { + bMineSound = TRUE; + StartMineSound(); + } +} + +void ArmorBattle_StopMineSound() +{ + if (bMineSound) + { + bMineSound = FALSE; + StopMineSound(); + } +} + +void ArmorBattle_DrawBlip(int nBright, int x, int y) +{ + blip[x][y].status = nBright; + + // update the looped mine sound + // this is not a good place for this + // should be in some sort of draw frame function + // maybe need to add that to the game structure + if (bMineSound){ + StartMineSound(); + } else { + StopMineSound(); + } +} + +void ArmorBattle_DrawTime(int nTime) +{ + if (nTime == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + if (nTime >= 10) + digit[0].val = nTime/10 + 1; + else + digit[0].val = -1; + // draw 1s place + digit[1].val = nTime%10 + 1; + } +} + +BOOL ArmorBattle_GetInputFIRE(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL ArmorBattle_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL ArmorBattle_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL ArmorBattle_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL ArmorBattle_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +void ArmorBattle_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_armorbattle.h b/source/platform/Platform_armorbattle.h new file mode 100644 index 0000000..008d289 --- /dev/null +++ b/source/platform/Platform_armorbattle.h @@ -0,0 +1,82 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __PLATFORM_ARMORBATTLE_H__ +#define __PLATFORM_ARMORBATTLE_H__ + +// [general] +#define armorbattle_digit_spacing 24 +#define armorbattle_digit_x 101 +#define armorbattle_digit_y 30 +#define armorbattle_digit_w 24 +#define armorbattle_digit_h 33 +#define armorbattle_blip_xspacing 3600 +#define armorbattle_blip_yspacing 3600 +#define armorbattle_blip_x 49 +#define armorbattle_blip_y 78 +#define armorbattle_power_x 42 +#define armorbattle_power_y 241 + +// interface that the platform must provide for this game + +// Input remapping +#define ARMORBATTLE_KEY_UP +#define ARMORBATTLE_KEY_DOWN +#define ARMORBATTLE_KEY_UP +#define ARMORBATTLE_KEY_UP + +// functions exported to the game context +void ArmorBattle_Init(); +void ArmorBattle_Help(); +void ArmorBattle_DeInit(); +void ArmorBattle_Paint(); +void ArmorBattle_ClearScreen(); +void ArmorBattle_PlaySound(int nSound, unsigned int nFlags); +void ArmorBattle_StopSound(); +void ArmorBattle_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void ArmorBattle_PlayMineSound(); +void ArmorBattle_StopMineSound(); +void ArmorBattle_DrawBlip(int nBright, int x, int y); +void ArmorBattle_DrawTime(int nTime); + +int ArmorBattle_GetInputLEFT(BOOL *pChange); +int ArmorBattle_GetInputUP(BOOL *pChange); +int ArmorBattle_GetInputRIGHT(BOOL *pChange); +int ArmorBattle_GetInputDOWN(BOOL *pChange); +int ArmorBattle_GetInputFIRE(BOOL *pChange); + +#endif diff --git a/source/platform/Platform_autorace.c b/source/platform/Platform_autorace.c new file mode 100644 index 0000000..82689d3 --- /dev/null +++ b/source/platform/Platform_autorace.c @@ -0,0 +1,582 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt.h" if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "autorace.h" +#include "skislalom_screen_png.h" +#include "skislalom_poweroff_png.h" +#include "skislalom_poweron_png.h" +#include "skislalom_gear1_png.h" +#include "skislalom_gear2_png.h" +#include "skislalom_gear3_png.h" +#include "skislalom_gear4_png.h" +#include "skislalom_aimleft_png.h" +#include "skislalom_aimcenter_png.h" +#include "skislalom_aimright_png.h" +#include "autorace_screen_png.h" +#include "autorace_poweroff_png.h" +#include "autorace_poweron_png.h" +#include "autorace_gear1_png.h" +#include "autorace_gear2_png.h" +#include "autorace_gear3_png.h" +#include "autorace_gear4_png.h" +#include "autorace_aimleft_png.h" +#include "autorace_aimcenter_png.h" +#include "autorace_aimright_png.h" +#include "autorace_gear1_raw.h" +#include "autorace_gear2_raw.h" +#include "autorace_gear3_raw.h" +#include "autorace_gear4_raw.h" +#include "autorace_hit_raw.h" +#include "autorace_time_raw.h" +#include "autorace_win_raw.h" +#include "skislalom_gear1_raw.h" +#include "skislalom_gear2_raw.h" +#include "skislalom_gear3_raw.h" +#include "skislalom_gear4_raw.h" +#include "skislalom_hit_raw.h" +#include "skislalom_time_raw.h" +#include "skislalom_win_raw.h" +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpPowerOn; +static GRRLIB_texImg *bmpGear1; +static GRRLIB_texImg *bmpGear2; +static GRRLIB_texImg *bmpGear3; +static GRRLIB_texImg *bmpGear4; +static GRRLIB_texImg *bmpAimLeft; +static GRRLIB_texImg *bmpAimCenter; +static GRRLIB_texImg *bmpAimRight; + +static int nStick = 1; + +static BOOL bEngineSound = FALSE; +static BOOL bEngineSoundPlaying = FALSE; + +// ************************************************** +// Ski Slalom is the exact same game as Auto Race, +// except the screen is flipped. I'm going to cheat +// and reuse as much of the Auto Race code as I can. +// This flag is used to toggle between the two games. +static BOOL bSkiSlalom = FALSE; +// ************************************************** + +static void StartEngineSound(); +static void StopEngineSound(); + +static Sound_t tcWaveRes[7]; +static Blip_t blip[AUTORACE_BLIP_COLUMNS][AUTORACE_BLIP_ROWS]; +static Stat_t digit[2]; +static Coord_t i_slider, i_power, i_gear; +static Help_t autorace_help[] = { + { WK_1, { 87, 90} }, + { WK_2, { 87, 144} }, + { WK_BUD, {89, 220} }, + { WK_LR, { 153, 264} } +}; + +static Help_t skislalom_help[] = { + { WK_1, { 87, 74} }, + { WK_2, { 87, 148} }, + { WK_BUD, {86, 205} }, + { WK_LR, { 154, 285} } +}; +//---------------------------------------------------------------------------- +// +// +void AutoRace_Help() +{ + Platform_Help(autorace_help, sizeof(autorace_help)/sizeof(*autorace_help)); +} + +void SkiSlalom_Help() +{ + Platform_Help(skislalom_help, sizeof(skislalom_help)/sizeof(*skislalom_help)); +} + +static BOOL bInited = FALSE; + +void SkiSlalom_Init() +{ + int x, y; + + bSkiSlalom = TRUE; + + // Init sounds + Sound_set(&tcWaveRes[0], skislalom_gear1_raw, skislalom_gear1_raw_size, 1324); + Sound_set(&tcWaveRes[1], skislalom_gear2_raw, skislalom_gear2_raw_size, 1051); + Sound_set(&tcWaveRes[2], skislalom_gear3_raw, skislalom_gear3_raw_size, 1045); + Sound_set(&tcWaveRes[3], skislalom_gear4_raw, skislalom_gear4_raw_size, 852); + Sound_set(&tcWaveRes[4], skislalom_hit_raw, skislalom_hit_raw_size, 137); + Sound_set(&tcWaveRes[5], skislalom_time_raw, skislalom_time_raw_size, 937); + Sound_set(&tcWaveRes[6], skislalom_win_raw, skislalom_win_raw_size, 1275); + + // load images + bmpScreen = GRRLIB_LoadTexture(skislalom_screen_png); + bmpPowerOff = GRRLIB_LoadTexture(skislalom_poweroff_png); + bmpPowerOn = GRRLIB_LoadTexture(skislalom_poweron_png); + bmpGear1 = GRRLIB_LoadTexture(skislalom_gear1_png); + bmpGear2 = GRRLIB_LoadTexture(skislalom_gear2_png); + bmpGear3 = GRRLIB_LoadTexture(skislalom_gear3_png); + bmpGear4 = GRRLIB_LoadTexture(skislalom_gear4_png); + bmpAimLeft = GRRLIB_LoadTexture(skislalom_aimleft_png); + bmpAimCenter = GRRLIB_LoadTexture(skislalom_aimcenter_png); + bmpAimRight = GRRLIB_LoadTexture(skislalom_aimright_png); + + // images position + i_slider.x = skislalom_slider_x; + i_slider.y = skislalom_slider_y; + i_power.x = skislalom_power_x; + i_power.y = skislalom_power_y; + i_gear.x = skislalom_gear_x; + i_gear.y = skislalom_gear_y; + + // set blips + for (y = 0; y < AUTORACE_BLIP_ROWS; y++){ + for (x = 0; x < AUTORACE_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)skislalom_blip_xspacing/100)) + skislalom_blip_x); + pblip->y = (int)((y * ((float)skislalom_blip_yspacing/100)) + skislalom_blip_y); + pblip->status = -1; + } + } + + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = skislalom_digit_x + x * skislalom_digit_spacing; + digit[x].y = skislalom_digit_y; + } + + if (!bInited) + { + PlatformSetInput(0); + + // turn on the game + AutoRace_SetSkill(0); + + // start with game off + AutoRace_PowerOff(); + + bInited = TRUE; + } +} + +void AutoRace_Init() +{ + int x, y; + + bSkiSlalom = FALSE; + + // Init sounds + Sound_set(&tcWaveRes[0], autorace_gear1_raw, autorace_gear1_raw_size, 1324); + Sound_set(&tcWaveRes[1], autorace_gear2_raw, autorace_gear2_raw_size, 1051); + Sound_set(&tcWaveRes[2], autorace_gear3_raw, autorace_gear3_raw_size, 1045); + Sound_set(&tcWaveRes[3], autorace_gear4_raw, autorace_gear4_raw_size, 852); + Sound_set(&tcWaveRes[4], autorace_hit_raw, autorace_hit_raw_size, 137); + Sound_set(&tcWaveRes[5], autorace_time_raw, autorace_time_raw_size, 937); + Sound_set(&tcWaveRes[6], autorace_win_raw, autorace_win_raw_size, 1275); + + // load images + bmpScreen = GRRLIB_LoadTexture(autorace_screen_png); + bmpPowerOff = GRRLIB_LoadTexture(autorace_poweroff_png); + bmpPowerOn = GRRLIB_LoadTexture(autorace_poweron_png); + bmpGear1 = GRRLIB_LoadTexture(autorace_gear1_png); + bmpGear2 = GRRLIB_LoadTexture(autorace_gear2_png); + bmpGear3 = GRRLIB_LoadTexture(autorace_gear3_png); + bmpGear4 = GRRLIB_LoadTexture(autorace_gear4_png); + bmpAimLeft = GRRLIB_LoadTexture(autorace_aimleft_png); + bmpAimCenter = GRRLIB_LoadTexture(autorace_aimcenter_png); + bmpAimRight = GRRLIB_LoadTexture(autorace_aimright_png); + + // images position + i_slider.x = autorace_slider_x; + i_slider.y = autorace_slider_y; + i_power.x = autorace_power_x; + i_power.y = autorace_power_y; + i_gear.x = autorace_gear_x; + i_gear.y = autorace_gear_y; + + // set blips + for (y = 0; y < AUTORACE_BLIP_ROWS; y++){ + for (x = 0; x < AUTORACE_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)autorace_blip_xspacing/100)) + autorace_blip_x); + pblip->y = (int)((y * ((float)autorace_blip_yspacing/100)) + autorace_blip_y); + pblip->status = -1; + } + } + + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = autorace_digit_x + x * autorace_digit_spacing; + digit[x].y = autorace_digit_y; + } + + if (!bInited) + { + PlatformSetInput(0); + + // turn on the game + AutoRace_SetSkill(0); + + // start with game off + AutoRace_PowerOff(); + + bInited = TRUE; + } +} + +void AutoRace_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + + bEngineSoundPlaying = FALSE; + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPowerOn); + GRRLIB_FreeTexture(bmpGear1); + GRRLIB_FreeTexture(bmpGear2); + GRRLIB_FreeTexture(bmpGear3); + GRRLIB_FreeTexture(bmpGear4); + GRRLIB_FreeTexture(bmpAimLeft); + GRRLIB_FreeTexture(bmpAimCenter); + GRRLIB_FreeTexture(bmpAimRight); + bInited = FALSE; +} + +void AutoRace_Paint() +{ + int x, y; + BOOL power = AutoRace_GetPower(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_SWITCH); + if(p_switch == -1 && power == TRUE) { + AutoRace_PowerOff(); + } + if(p_switch == 1 && power == FALSE) { + AutoRace_PowerOn(); + } + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // draw gear + switch (AutoRace_GetSkill()) + { + case 0: + GRRLIB_DrawImg(realx(i_gear.x), realy(i_gear.y), bmpGear1, 0, 1, 1, 0xFFFFFFFF); + break; + case 1: + GRRLIB_DrawImg(realx(i_gear.x), realy(i_gear.y), bmpGear2, 0, 1, 1, 0xFFFFFFFF); + break; + case 2: + GRRLIB_DrawImg(realx(i_gear.x), realy(i_gear.y), bmpGear3, 0, 1, 1, 0xFFFFFFFF); + break; + case 3: + GRRLIB_DrawImg(realx(i_gear.x), realy(i_gear.y), bmpGear4, 0, 1, 1, 0xFFFFFFFF); + break; + } + + // Draw stick + switch (nStick) + { + case 0: + GRRLIB_DrawImg(realx(i_slider.x), realy(i_slider.y), bmpAimLeft, 0, 1, 1, 0xFFFFFFFF); + break; + case 1: + GRRLIB_DrawImg(realx(i_slider.x), realy(i_slider.y), bmpAimCenter, 0, 1, 1, 0xFFFFFFFF); + break; + case 2: + GRRLIB_DrawImg(realx(i_slider.x), realy(i_slider.y), bmpAimRight, 0, 1, 1, 0xFFFFFFFF); + break; + } + + // Draw power + if (power) { + GRRLIB_DrawImg(realx(i_power.x), realy(i_power.y), bmpPowerOn, 0, 1, 1, 0xFFFFFFFF); + for (y = 0; y < AUTORACE_BLIP_ROWS; y++){ + for (x = 0; x < AUTORACE_BLIP_COLUMNS; x++){ + if(blip[x][y].status != -1) + draw_vblip(blip[x][y].x, blip[x][y].y, blip[x][y].status); + } + } + for(x = 0; x < sizeof(digit)/sizeof(*digit); x++) + draw_digit(digit[x].x, digit[x].y, digit[x].val); + } + else { + GRRLIB_DrawImg(realx(i_power.x), realy(i_power.y), bmpPowerOff, 0, 1, 1, 0xFFFFFFFF); + } + +} + +void AutoRace_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < AUTORACE_BLIP_ROWS; y++){ + for (int x = 0; x < AUTORACE_BLIP_COLUMNS; x++){ + AutoRace_DrawBlip(BLIP_OFF, x, y); + } + } + + // erase the score display + AutoRace_DrawTime(-1); + + Platform_EndDraw(); +} + +void AutoRace_PlaySound(int nSound, unsigned int nFlags) +{ + if ((nFlags & PLAYSOUNDFLAGS_PRIORITY) || bEngineSoundPlaying) + { + // stop any playing sounds first + Platform_StopSound(); + } + + // this sound will cut off any looping sounds + // note this so we can restart them later + bEngineSoundPlaying = FALSE; + + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void AutoRace_StopSound() +{ + bEngineSoundPlaying = FALSE; + bEngineSound = FALSE; + + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// +static void StartEngineSound() +{ + // if gear has changed, switch sounds + static int nOldGear = -1; + int nGear = AutoRace_GetSkill(); + if (nGear != nOldGear) + { + AutoRace_StopEngineSound(); + nOldGear = nGear; + } + + if (!bEngineSoundPlaying) + { + int nSound = AutoRace_GetSkill(); + + unsigned int nSoundFlags = PLAYSOUNDFLAGS_LOOP | PLAYSOUNDFLAGS_ASYNC; + Platform_PlaySound(&tcWaveRes[nSound], nSoundFlags); + // mark the sound as playing + bEngineSoundPlaying = TRUE; + } +} + +static void StopEngineSound() +{ + if (bEngineSoundPlaying) + { + Platform_StopSound(); + bEngineSoundPlaying = FALSE; + } +} + +void AutoRace_PlayEngineSound() +{ + if (!bEngineSound) + { + bEngineSound = TRUE; + StartEngineSound(); + } +} + +void AutoRace_StopEngineSound() +{ + if (bEngineSound) + { + bEngineSound = FALSE; + StopEngineSound(); + } +} + +void AutoRace_DrawBlip(int nBright, int x, int y) +{ + if (bSkiSlalom) + { + // flip the screen for ski slalom + y = (AUTORACE_BLIP_ROWS - 1) - y; + } + + switch(nBright){ + case BLIP_DIM: + blip[x][y].status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + blip[x][y].status = BLIP_TYPE_BRIGHT; + break; + case BLIP_OFF: + default: + blip[x][y].status = -1; + break; + } + + // update the looped engine sound + // this is not a good place for this + // should be in some sort of draw frame function + // maybe need to add that to the game structure + if (bEngineSound){ + StartEngineSound(); + } else { + StopEngineSound(); + } + +} + +void AutoRace_DrawTime(int nTime) +{ + if (nTime == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + if(nTime >= 10) + digit[0].val = nTime/10; + else + digit[0].val = -1; + // draw 1s place + digit[1].val = nTime%10 ; + } +} + +int AutoRace_GetInputSTICK() +{ + // check the keys + if (Platform_GetInputLEFT() + && !Platform_GetInputRIGHT()) + { + if (nStick != 0) + { + nStick = 0; + } + return nStick; + } + if (Platform_GetInputRIGHT() + && !Platform_GetInputLEFT()) + { + if (nStick != 2) + { + nStick = 2; + } + return nStick; + } + + // leave it where it was +// return nStick; + if (nStick != 1) + { + nStick = 1; + } + return nStick; +} + +int AutoRace_GetInputGEAR(BOOL *pChange) +{ + static BOOL bLastB = FALSE; + static BOOL bLastC = FALSE; + + if (pChange){ *pChange = FALSE; } + + int gear = AutoRace_GetSkill(); + + // check the keys + if (Platform_GetInput1()) + { + if (!bLastB) + { + // shift up + if (gear < 3) + { + ++gear; + AutoRace_SetSkill(gear); + if (pChange) + { + *pChange = TRUE; + } + } + bLastB = TRUE; + } + } + else + { + bLastB = FALSE; + } + + if (Platform_GetInput2()) + { + if (!bLastC) + { + // shift down + if (gear > 0) + { + --gear; + AutoRace_SetSkill(gear); + if (pChange) + { + *pChange = TRUE; + } + } + bLastC = TRUE; + } + } + else + { + bLastC = FALSE; + } + + return gear; +} + +void AutoRace_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} diff --git a/source/platform/Platform_autorace.h b/source/platform/Platform_autorace.h new file mode 100644 index 0000000..4de37b0 --- /dev/null +++ b/source/platform/Platform_autorace.h @@ -0,0 +1,98 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_AUTORACE_H__ +#define __PLATFORM_AUTORACE_H__ + +// [general] +#define autorace_digit_spacing 10 +#define autorace_digit_x 161 +#define autorace_digit_y 75 +#define autorace_digit_w 8 +#define autorace_digit_h 9 +#define autorace_blip_xspacing 1600 +#define autorace_blip_yspacing 1900 +#define autorace_blip_x 153 +#define autorace_blip_y 114 +#define autorace_slider_x 141 +#define autorace_slider_y 265 +#define autorace_power_x 91 +#define autorace_power_y 229 +#define autorace_gear_x 91 +#define autorace_gear_y 94 + +// [general] +#define skislalom_digit_spacing 10 +#define skislalom_digit_x 161 +#define skislalom_digit_y 95 +#define skislalom_digit_w 8 +#define skislalom_digit_h 9 +#define skislalom_blip_xspacing 1600 +#define skislalom_blip_yspacing 1900 +#define skislalom_blip_x 153 +#define skislalom_blip_y 134 +#define skislalom_slider_x 141 +#define skislalom_slider_y 285 +#define skislalom_power_x 91 +#define skislalom_power_y 229 +#define skislalom_gear_x 91 +#define skislalom_gear_y 94 + +// interface that the platform must provide for this game + +// functions exported to the game context +void SkiSlalom_Init(); +void SkiSlalom_Help(); + +void AutoRace_Init(); +void AutoRace_Help(); +void AutoRace_DeInit(); +void AutoRace_Paint(); +void AutoRace_ClearScreen(); +void AutoRace_PlaySound(int nSound, unsigned int nFlags); +void AutoRace_StopSound(); +void AutoRace_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void AutoRace_PlayEngineSound(); +void AutoRace_StopEngineSound(); +void AutoRace_DrawBlip(int nBright, int x, int y); +void AutoRace_DrawTime(int nTime); + +int AutoRace_GetInputSTICK(); +int AutoRace_GetInputGEAR(BOOL *pChange); + +#endif diff --git a/source/platform/Platform_baseball.c b/source/platform/Platform_baseball.c new file mode 100644 index 0000000..59ba5b8 --- /dev/null +++ b/source/platform/Platform_baseball.c @@ -0,0 +1,614 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "baseball.h" +#include "baseball_screen_png.h" +#include "baseball_blip_png.h" +#include "baseball_dimdigits_png.h" +#include "baseball_brightdigits_png.h" +#include "baseball_poweroff_png.h" +#include "baseball_pro1_png.h" +#include "baseball_pro2_png.h" +#include "baseball_hit_raw.h" +#include "baseball_out_raw.h" +#include "baseball_run_raw.h" +#include "baseball_strike_raw.h" +#include "baseball_endpossession_raw.h" +#include "baseball_endgame_raw.h" + +#define DIGIT_W 8 +#define DIGIT_H 12 + +#define DIGIT_TYPE_OFF 0 +#define DIGIT_TYPE_DIM 1 +#define DIGIT_TYPE_BRIGHT 2 + +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpBlip; +static GRRLIB_texImg *bmpDimDigits; +static GRRLIB_texImg *bmpBrightDigits; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpPro1; +static GRRLIB_texImg *bmpPro2; + +static Sound_t tcWaveRes[6]; + +static Digit_t digit[4] = { + { baseball_digit1_x, baseball_digit_y, 0, DIGIT_TYPE_OFF}, + { baseball_digit2_x, baseball_digit_y, 0, DIGIT_TYPE_OFF}, + { baseball_digit3_x, baseball_digit_y, 0, DIGIT_TYPE_OFF}, + { baseball_digit4_x, baseball_digit_y, 0, DIGIT_TYPE_OFF} +}; + +// blips for normal pitches +static Blip_t blip_pitch[9] = { + { baseball_blip_pitch_1_x, baseball_blip_pitch_1_y, BLIP_OFF }, + { baseball_blip_pitch_2_x, baseball_blip_pitch_2_y, BLIP_OFF }, + { baseball_blip_pitch_3_x, baseball_blip_pitch_3_y, BLIP_OFF }, + { baseball_blip_pitch_4_x, baseball_blip_pitch_4_y, BLIP_OFF }, + { baseball_blip_pitch_5_x, baseball_blip_pitch_5_y, BLIP_OFF }, + { baseball_blip_pitch_6_x, baseball_blip_pitch_6_y, BLIP_OFF }, + { baseball_blip_pitch_7_x, baseball_blip_pitch_7_y, BLIP_OFF }, + { baseball_blip_pitch_8_x, baseball_blip_pitch_8_y, BLIP_OFF }, + { baseball_blip_pitch_9_x, baseball_blip_pitch_9_y, BLIP_OFF } +}; +// blips for curve balls +static Blip_t blip_pitchcurve[4] = { + { baseball_blip_pitchcurve_2_x, baseball_blip_pitchcurve_2_y, BLIP_OFF }, + { baseball_blip_pitchcurve_3_x, baseball_blip_pitchcurve_3_y, BLIP_OFF }, + { baseball_blip_pitchcurve_4_x, baseball_blip_pitchcurve_4_y, BLIP_OFF }, + { baseball_blip_pitchcurve_5_x, baseball_blip_pitchcurve_5_y, BLIP_OFF } +}; +// blips bases +static Blip_t blip_base[4][3] = { + // blips for home plate -> 1st base + {{ baseball_blip_base_0_x,baseball_blip_base_0_y, BLIP_OFF }, + { baseball_blip_base_0A_x,baseball_blip_base_0A_y, BLIP_OFF }, + { baseball_blip_base_0B_x,baseball_blip_base_0B_y, BLIP_OFF }}, + // blips for 1st base -> 2nd base + {{ baseball_blip_base_1_x,baseball_blip_base_1_y, BLIP_OFF }, + { baseball_blip_base_1A_x,baseball_blip_base_1A_y, BLIP_OFF }, + { baseball_blip_base_1B_x,baseball_blip_base_1B_y, BLIP_OFF }}, + {{ baseball_blip_base_2_x,baseball_blip_base_2_y, BLIP_OFF }, + // blips for 2nd base -> 3rd base + { baseball_blip_base_2A_x,baseball_blip_base_2A_y, BLIP_OFF }, + { baseball_blip_base_2B_x,baseball_blip_base_2B_y, BLIP_OFF }}, + // blips for 3rd base -> home plate + {{ baseball_blip_base_3_x,baseball_blip_base_3_y, BLIP_OFF }, + { baseball_blip_base_3A_x,baseball_blip_base_3A_y, BLIP_OFF }, + { baseball_blip_base_3B_x,baseball_blip_base_3B_y, BLIP_OFF }} +}; +// blips deep +static Blip_t blip_deep[2] = { + // blip for deep 1st + { baseball_blip_deep1st_x,baseball_blip_deep1st_y, BLIP_OFF }, + // blip for deep 3rd + { baseball_blip_deep3rd_x,baseball_blip_deep3rd_y, BLIP_OFF } +}; +// blips for outfield +static Blip_t blip_outfield[3] = { + { baseball_blip_outfield_left_x,baseball_blip_outfield_left_y, BLIP_OFF }, + { baseball_blip_outfield_center_x,baseball_blip_outfield_center_y, BLIP_OFF }, + { baseball_blip_outfield_right_x,baseball_blip_outfield_right_y, BLIP_OFF } +}; + +static Help_t help[] = { + { WK_1, {195, 247} }, + { WK_2, {195, 280} }, + { WK_PLUS, {22, 247} }, + { WK_MINUS, {22, 280} }, + { WK_BLR, {94, 258} } +}; +//---------------------------------------------------------------------------- +// +// +void Baseball_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void Baseball_Init() +{ + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], baseball_hit_raw, baseball_hit_raw_size, 82 ); + Sound_set(&tcWaveRes[1], baseball_out_raw, baseball_out_raw_size, 392 ); + Sound_set(&tcWaveRes[2], baseball_run_raw, baseball_run_raw_size, 423 ); + Sound_set(&tcWaveRes[3], baseball_strike_raw, baseball_strike_raw_size, 22 ); + Sound_set(&tcWaveRes[4], baseball_endpossession_raw, baseball_endpossession_raw_size, 560 ); + Sound_set(&tcWaveRes[5], baseball_endgame_raw, baseball_endgame_raw_size, 712 ); + + // load images + bmpScreen = GRRLIB_LoadTexture(baseball_screen_png); + bmpBlip = GRRLIB_LoadTexture(baseball_blip_png); + bmpDimDigits = GRRLIB_LoadTexture(baseball_dimdigits_png); + GRRLIB_InitTileSet(bmpDimDigits, DIGIT_W, DIGIT_H, 0); + bmpBrightDigits = GRRLIB_LoadTexture(baseball_brightdigits_png); + GRRLIB_InitTileSet(bmpBrightDigits, DIGIT_W, DIGIT_H, 0); + + // set up the power switch images + bmpPowerOff = GRRLIB_LoadTexture(baseball_poweroff_png); + bmpPro1 = GRRLIB_LoadTexture(baseball_pro1_png); + bmpPro2 = GRRLIB_LoadTexture(baseball_pro2_png); + + PlatformSetInput(0); + // turn on the game + Baseball_SetSkill(0); + Baseball_PowerOn(); + + bInited = TRUE; +} + +void Baseball_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpBlip); + GRRLIB_FreeTexture(bmpDimDigits); + GRRLIB_FreeTexture(bmpBrightDigits); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPro1); + GRRLIB_FreeTexture(bmpPro2); + + bInited = FALSE; +} + +void Baseball_Paint() +{ + int i; + BOOL power = Baseball_GetPower(); + BOOL skill = Baseball_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_OFF12); + if(power) { + if(p_switch == -1) { + if(skill == 0) + Baseball_PowerOff(); + if(skill == 1) { + Baseball_PowerOn(); + Baseball_SetSkill(0); + } + } + if(p_switch == 1) { + if(skill == 0) { + Baseball_PowerOn(); + Baseball_SetSkill(1); + } + } + } + else { + if(p_switch == 1) { + Baseball_PowerOn(); + Baseball_SetSkill(0); + } + } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + if (power) + { + if (skill == 0) + { + GRRLIB_DrawImg(realx(baseball_pro_1_x), realy(baseball_pro_1_y), bmpPro1, 0, 1, 1, 0xFFFFFFFF); + } + else { + GRRLIB_DrawImg(realx(baseball_pro_2_x), realy(baseball_pro_2_y), bmpPro2, 0, 1, 1, 0xFFFFFFFF); + } + // show blips + for(i=0; i<9; i++) { + Blip_t *pblip = &blip_pitch[i]; + if(pblip->status != BLIP_OFF) + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlip, 0, 1, 1, 0xFFFFFFFF); + } + for(i=0; i<4; i++) { + Blip_t *pblip = &blip_pitchcurve[i]; + if(pblip->status != BLIP_OFF) + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlip, 0, 1, 1, 0xFFFFFFFF); + } + for(i=0; i<4; i++) { + int j; + for(j=0; j<3; j++) { + Blip_t *pblip = &blip_base[i][j]; + if(pblip->status != BLIP_OFF) + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlip, 0, 1, 1, 0xFFFFFFFF); + } + } + for(i=0; i<2; i++) { + Blip_t *pblip = &blip_deep[i]; + if(pblip->status != BLIP_OFF) + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlip, 0, 1, 1, 0xFFFFFFFF); + } + for(i=0; i<3; i++) { + Blip_t *pblip = &blip_outfield[i]; + if(pblip->status != BLIP_OFF) + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlip, 0, 1, 1, 0xFFFFFFFF); + } + + // show digits + for(i=0; i<4; i++) { + Digit_t *pdigit = &digit[i]; + + switch(pdigit->type) { + case DIGIT_TYPE_DIM: + GRRLIB_DrawTile(realx(pdigit->x), realy(pdigit->y), bmpDimDigits, 0, 1, 1, 0xFFFFFFFF, pdigit->val + 1); + break; + case DIGIT_TYPE_BRIGHT: + GRRLIB_DrawTile(realx(pdigit->x), realy(pdigit->y), bmpBrightDigits, 0, 1, 1, 0xFFFFFFFF, pdigit->val + 1); + break; + case DIGIT_TYPE_OFF: + default: + break; + } + } + } + else + { + GRRLIB_DrawImg(realx(baseball_power_off_x), realy(baseball_power_off_y), bmpPowerOff, 0, 1, 1, 0xFFFFFFFF); + } +} + +void Baseball_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void Baseball_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void Baseball_DrawPitchBlip(BOOL state, int index, BOOL curve) +{ + Blip_t *pblip = NULL; + + switch(index) + { + case 0: + default: + pblip = &blip_pitch[0]; + break; + case 1: + if (curve) + pblip = &blip_pitchcurve[0]; + else + pblip = &blip_pitch[1]; + break; + case 2: + if (curve) + pblip = &blip_pitchcurve[1]; + else + pblip = &blip_pitch[2]; + break; + case 3: + if (curve) + pblip = &blip_pitchcurve[2]; + else + pblip = &blip_pitch[3]; + break; + case 4: + if (curve) + pblip = &blip_pitchcurve[3]; + else + pblip = &blip_pitch[4]; + break; + case 5: + pblip = &blip_pitch[5]; + break; + case 6: + pblip = &blip_pitch[6]; + break; + case 7: + pblip = &blip_pitch[7]; + break; + case 8: + pblip = &blip_pitch[8]; + break; + } + + if (pblip != NULL ) + { + pblip->status = (state) ? BLIP_DIM : BLIP_OFF; + } +} + +void Baseball_DrawBaseBlip(BOOL state, int index) +{ + Blip_t *pblip = NULL; + + switch(index) + { + case 12: + case 0: // home plate + pblip = &blip_base[0][0]; + break; + case 1: + pblip = &blip_base[0][1]; + break; + case 2: + pblip = &blip_base[0][2]; + break; + case 3: // 1st base + pblip = &blip_base[1][0]; + break; + case 4: + pblip = &blip_base[1][1]; + break; + case 5: + pblip = &blip_base[1][2]; + break; + case 6: // 2nd base + pblip = &blip_base[2][0]; + break; + case 7: + pblip = &blip_base[2][1]; + break; + case 8: + pblip = &blip_base[2][2]; + break; + case 9: // 3rd + pblip = &blip_base[3][0]; + break; + case 10: + pblip = &blip_base[3][1]; + break; + case 11: + pblip = &blip_base[3][2]; + break; + } + if (pblip != NULL ) + { + pblip->status = (state) ? BLIP_DIM : BLIP_OFF; + } +} + +void Baseball_DrawOutfieldBlip(BOOL state, int index) +{ + Blip_t *pblip = &blip_outfield[index]; + + pblip->status = (state) ? BLIP_DIM : BLIP_OFF; +} + +void Baseball_DrawDeepBlip(BOOL state, int index) +{ + Blip_t *pblip = &blip_deep[index]; + + pblip->status = (state) ? BLIP_DIM : BLIP_OFF; +} + +void Baseball_DrawStats(int innings, int outs, int balls, int strikes, BOOL bHomeTeam) +{ + Digit_t *pdigit = &digit[0]; + + // innings + if (innings == -1) + { + pdigit->val = -1; + pdigit->type = DIGIT_TYPE_DIM; + } + else + { + pdigit->val = innings; + pdigit->type = DIGIT_TYPE_DIM; + } + + // outs + pdigit++; + if (outs == -1) + { + pdigit->val = -1; + pdigit->type = DIGIT_TYPE_DIM; + } + else + { + if (bHomeTeam) + { + pdigit->val = outs; + pdigit->type = DIGIT_TYPE_DIM; + } + else + { + // draw decimal + pdigit->val = outs+11; + pdigit->type = DIGIT_TYPE_DIM; + } + } + + // balls + pdigit++; + pdigit->val = balls; + pdigit->type = DIGIT_TYPE_DIM; + + // strikes + pdigit++; + if (bHomeTeam) + { + // draw decimal + pdigit->val = strikes+11; + pdigit->type = DIGIT_TYPE_DIM; + } + else + { + pdigit->val = strikes; + pdigit->type = DIGIT_TYPE_DIM; + } +} + +void Baseball_DrawScore(int vruns, int hruns) +{ + if ((vruns==-1) && (hruns==-1)) + { + // erase the digits display + int i; + for(i=0; i <4; i++) { + digit[i].val = -1; + digit[i].type = DIGIT_TYPE_BRIGHT; + } + } + else + { + int i; + for(i=0; i <4; i++) { + digit[i].type = DIGIT_TYPE_BRIGHT; + } + // draw visitors 10s place + digit[0].val = vruns/10; + + // draw visitors 1s place + digit[1].val = vruns%10; + + // draw home 10s place + digit[2].val = hruns/10; + + // draw home 1s place + digit[3].val = hruns%10; + } +} + +void Baseball_DrawFireWorks(void) +{ + int i; + + for(i=0; i <4; i++) { + digit[i].val = -1; + digit[i].type = (i == 1) ? DIGIT_TYPE_BRIGHT : DIGIT_TYPE_DIM; + } +} + +BOOL Baseball_GetInputSCORE(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputPLUS()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Baseball_GetInputPITCH(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputMINUS()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Baseball_GetInputHIT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetRealTimeInput2()) // NOTE: gets realtime key state + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Baseball_GetInputRUN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput1()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +void Baseball_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_baseball.h b/source/platform/Platform_baseball.h new file mode 100644 index 0000000..7104d35 --- /dev/null +++ b/source/platform/Platform_baseball.h @@ -0,0 +1,159 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_BASEBALL_H__ +#define __PLATFORM_BASEBALL_H__ + +// [general] +#define baseball_power_off_x 91 +#define baseball_power_off_y 300 +#define baseball_pro_1_x 91 +#define baseball_pro_1_y 300 +#define baseball_pro_2_x 91 +#define baseball_pro_2_y 300 +#define baseball_digit1_x 73 +#define baseball_digit2_x 102 +#define baseball_digit3_x 131 +#define baseball_digit4_x 160 +#define baseball_digit_y 34 +#define baseball_digit_w 8 +#define baseball_digit_h 9 + +// blips for normal pitches +#define baseball_blip_pitch_1_x 118 +#define baseball_blip_pitch_1_y 151 +#define baseball_blip_pitch_2_x 118 +#define baseball_blip_pitch_2_y 167 +#define baseball_blip_pitch_3_x 118 +#define baseball_blip_pitch_3_y 182 +#define baseball_blip_pitch_4_x 118 +#define baseball_blip_pitch_4_y 197 +#define baseball_blip_pitch_5_x 118 +#define baseball_blip_pitch_5_y 211 +#define baseball_blip_pitch_6_x 118 +#define baseball_blip_pitch_6_y 225 +#define baseball_blip_pitch_7_x 118 +#define baseball_blip_pitch_7_y 236 +#define baseball_blip_pitch_8_x 118 +#define baseball_blip_pitch_8_y 248 +#define baseball_blip_pitch_9_x 118 +#define baseball_blip_pitch_9_y 256 + +// blips for curve balls +#define baseball_blip_pitchcurve_2_x 123 +#define baseball_blip_pitchcurve_2_y 166 +#define baseball_blip_pitchcurve_3_x 125 +#define baseball_blip_pitchcurve_3_y 181 +#define baseball_blip_pitchcurve_4_x 125 +#define baseball_blip_pitchcurve_4_y 196 +#define baseball_blip_pitchcurve_5_x 123 +#define baseball_blip_pitchcurve_5_y 210 + +// home plate -> 1st base +#define baseball_blip_base_0_x 118 +#define baseball_blip_base_0_y 236 +#define baseball_blip_base_0A_x 138 +#define baseball_blip_base_0A_y 215 +#define baseball_blip_base_0B_x 160 +#define baseball_blip_base_0B_y 192 + +// 1st base -> 2nd base +#define baseball_blip_base_1_x 184 +#define baseball_blip_base_1_y 168 +#define baseball_blip_base_1A_x 165 +#define baseball_blip_base_1A_y 145 +#define baseball_blip_base_1B_x 142 +#define baseball_blip_base_1B_y 121 + +// 2nd base -> 3rd base +#define baseball_blip_base_2_x 118 +#define baseball_blip_base_2_y 99 +#define baseball_blip_base_2A_x 93 +#define baseball_blip_base_2A_y 121 +#define baseball_blip_base_2B_x 72 +#define baseball_blip_base_2B_y 144 + +// 3rd base -> home plate +#define baseball_blip_base_3_x 52 +#define baseball_blip_base_3_y 167 +#define baseball_blip_base_3A_x 76 +#define baseball_blip_base_3A_y 192 +#define baseball_blip_base_3B_x 98 +#define baseball_blip_base_3B_y 215 + +// deep 1st +#define baseball_blip_deep1st_x 191 +#define baseball_blip_deep1st_y 148 + +// deep 3rd +#define baseball_blip_deep3rd_x 45 +#define baseball_blip_deep3rd_y 148 + +// outfield +#define baseball_blip_outfield_left_x 53 +#define baseball_blip_outfield_left_y 85 +#define baseball_blip_outfield_center_x 119 +#define baseball_blip_outfield_center_y 65 +#define baseball_blip_outfield_right_x 184 +#define baseball_blip_outfield_right_y 85 + +// interface that the platform must provide for this game + +// functions exported to the game context +void Baseball_Init(); +void Baseball_Help(); +void Baseball_DeInit(); +void Baseball_Paint(); +void Baseball_PlaySound(int nSound, unsigned int nFlags); +void Baseball_StopSound(); +void Baseball_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void Baseball_DrawPitchBlip(BOOL state, int index, BOOL curve); +void Baseball_DrawBaseBlip(BOOL state, int index); +void Baseball_DrawOutfieldBlip(BOOL state, int index); +void Baseball_DrawDeepBlip(BOOL state, int index); + +void Baseball_DrawStats(int innings, int outs, int balls, int strikes, BOOL bHomeTeam); +void Baseball_DrawScore(int vruns, int hruns); +void Baseball_DrawFireWorks(void); + +BOOL Baseball_GetInputSCORE(BOOL *pChange); +BOOL Baseball_GetInputPITCH(BOOL *pChange); +BOOL Baseball_GetInputHIT(BOOL *pChange); +BOOL Baseball_GetInputRUN(BOOL *pChange); + +#endif diff --git a/source/platform/Platform_basketball.c b/source/platform/Platform_basketball.c new file mode 100644 index 0000000..57dc873 --- /dev/null +++ b/source/platform/Platform_basketball.c @@ -0,0 +1,395 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "basketball.h" +#include "basketball_screen_png.h" +#include "basketball_tick_raw.h" +#include "basketball_bounce_raw.h" +#include "basketball_score_raw.h" +#include "basketball_endplay_raw.h" +#include "basketball_endquarter_raw.h" +#include "basketball_endgame_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; + +static Sound_t tcWaveRes[6]; +static Blip_t blip[BASKETBALL_BLIP_COLUMNS][BASKETBALL_BLIP_ROWS]; +static Blip_t basket; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, { 183, 232} }, + { WK_BLR, {27, 275} }, + { WK_DPAD, { 105, 242} } +}; +//---------------------------------------------------------------------------- +// +// +void Basketball_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void Basketball_Init() +{ + int x, y; + + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], basketball_tick_raw, basketball_tick_raw_size, 27); + Sound_set(&tcWaveRes[1], basketball_bounce_raw, basketball_bounce_raw_size, 50); + Sound_set(&tcWaveRes[2], basketball_score_raw, basketball_score_raw_size, 799); + Sound_set(&tcWaveRes[3], basketball_endplay_raw, basketball_endplay_raw_size, 721); + Sound_set(&tcWaveRes[4], basketball_endquarter_raw, basketball_endquarter_raw_size, 1878); + Sound_set(&tcWaveRes[5], basketball_endgame_raw, basketball_endgame_raw_size, 3753); + + // load images + bmpScreen = GRRLIB_LoadTexture(basketball_screen_png); + + // set blips + for (y = 0; y < BASKETBALL_BLIP_ROWS; y++){ + for (x = 0; x < BASKETBALL_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)basketball_blip_xspacing/100)) + basketball_blip_x); + pblip->y = (int)((y * ((float)basketball_blip_yspacing/100)) + basketball_blip_y); + pblip->status = -1; + } + } + basket.x = basketball_basket_x; + basket.y = basketball_basket_y; + basket.status = -1; + + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = basketball_digit_x + x * basketball_digit_spacing; + digit[x].y = basketball_digit_y; + } + + PlatformSetInput(0); + // turn on the game + Basketball_SetSkill(0); + Basketball_PowerOn(); + + bInited = TRUE; +} + +void Basketball_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + bInited = FALSE; +} + +void Basketball_Paint() +{ + int x, y; + BOOL power = Basketball_GetPower(); + BOOL skill = Basketball_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_1OFF2); + if(p_switch == -1) { + if(!power) { + Basketball_PowerOn(); + Basketball_SetSkill(0); + } + else if(power && skill == 1) { + Basketball_PowerOff(); + } + } + else if(p_switch == 1) { + if(!power) { + Basketball_PowerOn(); + Basketball_SetSkill(1); + } + else if(power && skill == 0) { + Basketball_PowerOff(); + } + } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power){ + if (skill == 0){ + draw_poweroff_a(basketball_pro_1_x, basketball_pro_1_y, POWER_POS_MODE1); + } else { + draw_poweroff_a(basketball_pro_2_x, basketball_pro_2_y, POWER_POS_MODE2); + } + + for (y = 0; y < BASKETBALL_BLIP_ROWS; y++){ + for (x = 0; x < BASKETBALL_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + if(pblip->status != -1) + draw_vblip(pblip->x, pblip->y, pblip->status); + } + } + if(basket.status != -1) + draw_vblip(basket.x, basket.y, basket.status); + for(x = 0; x < 2; x++) + draw_digit(digit[x].x, digit[x].y, digit[x].val); + } + else { + draw_poweroff_a(basketball_power_off_x, basketball_power_off_y, POWER_POS_OFF); + } +} + +void Basketball_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < BASKETBALL_BLIP_ROWS; y++){ + for (int x = 0; x < BASKETBALL_BLIP_COLUMNS; x++){ + Basketball_DrawBlip(BLIP_OFF, x, y); + } + } + + Basketball_DrawBasket(FALSE); + + // erase the stat display + Basketball_DrawStat(-1); + + Platform_EndDraw(); +} + +void Basketball_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void Basketball_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void Basketball_DrawBlip(int nBright, int x, int y) +{ + switch(nBright){ + case BLIP_DIM: + blip[x][y].status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + blip[x][y].status = BLIP_TYPE_BRIGHT; + break; + case BLIP_OFF: + default: + blip[x][y].status = -1; + break; + } +} + +void Basketball_DrawStat(int nStat) +{ + if (nStat == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + digit[0].val = nStat/10; + // draw 1s place + digit[1].val = nStat%10; + } +} + +void Basketball_DrawBasket(BOOL bBasket) +{ + Platform_StartDraw(); + + if (bBasket) + { + int x, y; + + // erase the blips + for (y = 0; y < BASKETBALL_BLIP_ROWS; y++){ + for (x = 0; x < BASKETBALL_BLIP_COLUMNS; x++){ + Basketball_DrawBlip(BLIP_OFF, x, y); + } + } + // draw the basket + basket.status = BLIP_TYPE_BRIGHT; + } + else + { + // erase the basket + basket.status = -1; + } + + Platform_EndDraw(); +} + +BOOL Basketball_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Basketball_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Basketball_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Basketball_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Basketball_GetInputTHROW(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Basketball_TestForMovement() +{ + // check the keys + if (Platform_GetInputLEFT() + || Platform_GetInputUP() + || Platform_GetInputRIGHT() + || Platform_GetInputDOWN() + || Platform_GetInput2()) + { + return TRUE; + } + + return FALSE; +} + +void Basketball_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} diff --git a/source/platform/Platform_basketball.h b/source/platform/Platform_basketball.h new file mode 100644 index 0000000..70f4453 --- /dev/null +++ b/source/platform/Platform_basketball.h @@ -0,0 +1,83 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_BASKETBALL_H__ +#define __PLATFORM_BASKETBALL_H__ + +// [general] +#define basketball_digit_spacing 12 +#define basketball_digit_x 110 +#define basketball_digit_y 197 +#define basketball_digit_w 8 +#define basketball_digit_h 9 +#define basketball_blip_xspacing 3500 +#define basketball_blip_yspacing 3400 +#define basketball_blip_x 50 +#define basketball_blip_y 72 +#define basketball_power_off_x 27 +#define basketball_power_off_y 274 +#define basketball_pro_1_x 27 +#define basketball_pro_1_y 274 +#define basketball_pro_2_x 27 +#define basketball_pro_2_y 274 +#define basketball_basket_x 120 +#define basketball_basket_y 51 + +// interface that the platform must provide for this game + +// functions exported to the game context +void Basketball_Init(); +void Basketball_Help(); +void Basketball_DeInit(); +void Basketball_Paint(); +void Basketball_ClearScreen(); +void Basketball_PlaySound(int nSound, unsigned int nFlags); +void Basketball_StopSound(); +void Basketball_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void Basketball_DrawBlip(int nBright, int x, int y); +void Basketball_DrawStat(int nStat); +void Basketball_DrawBasket(BOOL bBasket); + +BOOL Basketball_GetInputLEFT(BOOL *pChange); +BOOL Basketball_GetInputUP(BOOL *pChange); +BOOL Basketball_GetInputRIGHT(BOOL *pChange); +BOOL Basketball_GetInputDOWN(BOOL *pChange); +BOOL Basketball_GetInputTHROW(BOOL *pChange); +BOOL Basketball_TestForMovement(); + +#endif diff --git a/source/platform/Platform_football.c b/source/platform/Platform_football.c new file mode 100644 index 0000000..b338802 --- /dev/null +++ b/source/platform/Platform_football.c @@ -0,0 +1,572 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "football.h" +#include "football_screen_png.h" +#include "football_poweroff_png.h" +#include "football_pro1_png.h" +#include "football_pro2_png.h" +#include "football_tick_raw.h" +#include "football_endplay_raw.h" +#include "football_endpossession_raw.h" +#include "football_score_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpPro1; +static GRRLIB_texImg *bmpPro2; + +static Sound_t tcWaveRes[4]; +static Blip_t blip[FOOTBALL_BLIP_COLUMNS][FOOTBALL_BLIP_ROWS]; +static Digit_t digit[7] = { + {football_digit_x, football_digit_y, -1}, + {football_digit_x + football_digit_spacing, football_digit_y, -1, -1}, + {football_digit_x + (4 * football_digit_spacing), football_digit_y, -1, -1}, + {football_digit_x + (5 * football_digit_spacing), football_digit_y, -1, -1}, + {football_digit_x + (6 * football_digit_spacing), football_digit_y, -1, -1}, + {football_digit_x + (9 * football_digit_spacing), football_digit_y, -1, -1}, + {football_digit_x + (10 * football_digit_spacing), football_digit_y, -1, -1} +}; +static Help_t help[] = { + { WK_2, { 74, 205} }, + { WK_MINUS, { 30, 230} }, + { WK_PLUS, { 30, 184} }, + { WK_BLR, { 92, 285 } }, + { WK_UD, { 187, 201 } }, + { WK_LR, { 140, 201 } } +}; +//---------------------------------------------------------------------------- +// +// +void Football_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void Football_Init() +{ + int x, y; + + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], football_tick_raw, football_tick_raw_size, 25); + Sound_set(&tcWaveRes[1], football_endplay_raw, football_endplay_raw_size, 489); + Sound_set(&tcWaveRes[2], football_endpossession_raw, football_endpossession_raw_size, 984); + Sound_set(&tcWaveRes[3], football_score_raw, football_score_raw_size, 1335); + + // load images + bmpScreen = GRRLIB_LoadTexture(football_screen_png); + + // set up the power switch images + bmpPowerOff = GRRLIB_LoadTexture(football_poweroff_png); + bmpPro1 = GRRLIB_LoadTexture(football_pro1_png); + bmpPro2 = GRRLIB_LoadTexture(football_pro2_png); + + // init blips positions + for (y = 0; y < FOOTBALL_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)football_blip_xspacing/100)) + football_blip_x); + pblip->y = (int)((y * ((float)football_blip_yspacing/100)) + football_blip_y); + pblip->status = -1; + } + } + // clean digit + for (x=0; x<7; x++) { + digit[x].val = -1; + digit[x].type = DIGIT_TYPE_NORMAL; + } + + PlatformSetInput(0); + // turn on the game + Football_SetSkill(0); + Football_PowerOn(); + + bInited = TRUE; +} + +void Football_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPro1); + GRRLIB_FreeTexture(bmpPro2); + bInited = FALSE; +} + +void Football_Paint() +{ + int x, y; + BOOL power = Football_GetPower(); + BOOL skill = Football_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_OFF12); + if(power) { + if(p_switch == -1) { + if(skill == 0) + Football_PowerOff(); + if(skill == 1) { + Football_PowerOn(); + Football_SetSkill(0); + } + } + if(p_switch == 1) { + if(skill == 0) { + Football_PowerOn(); + Football_SetSkill(1); + } + } + } + else { + if(p_switch == 1) { + Football_PowerOn(); + Football_SetSkill(0); + } + } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xffffffff); + // visualize the control states + if (power){ + if (skill == 0){ + GRRLIB_DrawImg(realx(football_pro_1_x), realy(football_pro_1_y), bmpPro1, 0, 1, 1, 0xffffffff); + } else { + GRRLIB_DrawImg(realx(football_pro_2_x), realy(football_pro_2_y), bmpPro2, 0, 1, 1, 0xffffffff); + } + + for (y = 0; y < FOOTBALL_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL_BLIP_COLUMNS; x++){ + if(blip[x][y].status != -1) + draw_oblip(blip[x][y].x, blip[x][y].y, blip[x][y].status); + } + } + for(x = 0; x < 7; x++) { + draw_digit_f(digit[x].x, digit[x].y, digit[x].val, digit[x].type); + } + } + else { + GRRLIB_DrawImg(realx(football_power_off_x), realy(football_power_off_y), bmpPowerOff, 0, 1, 1, 0xffffffff); + } + +} + +void Football_ClearScreen() +{ + int x, y; + + Platform_StartDraw(); + + // erase the blips + for (y = 0; y < FOOTBALL_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL_BLIP_COLUMNS; x++){ + Football_DrawBlip(BLIP_OFF, x, y); + } + } + // erase the stat display + Football_DrawScores(-1, -1); + Football_DrawTime(-1); + + Platform_EndDraw(); +} + +void Football_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void Football_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void Football_DrawBlip(int nBright, int x, int y) +{ + Blip_t *pblip = &blip[x][y]; + + switch(nBright){ + case BLIP_OFF: + pblip->status = -1; + break; + case BLIP_DIM: + pblip->status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + pblip->status = BLIP_TYPE_BRIGHT; + break; + } +} + +void Football_DrawScores(int nHScore, int nVScore) +{ + // draw home team score + if (nHScore == -1){ + // erase the time + digit[0].val = -1; + digit[0].type = DIGIT_TYPE_NORMAL; + digit[1].val = -1; + digit[1].type = DIGIT_TYPE_NORMAL; + } else { + + // draw 10s place + if ((nHScore/10) != 0){ + digit[0].val = nHScore/10; + } else { + digit[0].val = -1; + } + digit[0].type = DIGIT_TYPE_NORMAL; + + // draw 1s place + digit[1].val = nHScore%10; + digit[1].type = DIGIT_TYPE_NORMAL; + } + + // draw visitor team score + if (nVScore == -1){ + // erase the time + digit[5].val = -1; + digit[5].type = DIGIT_TYPE_NORMAL; + digit[6].val = -1; + digit[6].type = DIGIT_TYPE_NORMAL; + } else { + // draw 10s place + if ((nVScore/10) != 0){ + digit[5].val = nVScore/10; + } else { + digit[5].val = -1; + } + digit[5].type = DIGIT_TYPE_NORMAL; + // draw 1s place + digit[6].val = nVScore%10; + digit[6].type = DIGIT_TYPE_NORMAL; + } +} + +void Football_DrawDown(int nDown, int nYards) +{ + // draw downs + if (nDown == -1){ + // erase the down + digit[0].val = -1; + digit[0].type = DIGIT_TYPE_NORMAL; + digit[1].val = -1; + digit[1].type = DIGIT_TYPE_NORMAL; + } else { + ++nDown; + + // draw 10s place + if (nDown >= 10){ + digit[0].val = nDown/10; + } else { + digit[0].val = -1; + } + digit[0].type = DIGIT_TYPE_NORMAL; + + // draw 1s place + digit[1].val = nDown%10; + digit[1].type = DIGIT_TYPE_NORMAL; + } + + // draw yards + if (nYards <= 0){ + // erase the yards + digit[5].val = -1; + digit[5].type = DIGIT_TYPE_NORMAL; + digit[6].val = -1; + digit[6].type = DIGIT_TYPE_NORMAL; + } else { + // draw 10s place + if (nYards >= 10){ + digit[5].val = nYards/10; + } else { + digit[5].val = -1; + } + digit[5].type = DIGIT_TYPE_NORMAL; + + // draw 1s place + digit[6].val = nYards%10; + digit[6].type = DIGIT_TYPE_NORMAL; + } +} + +void Football_DrawTime(float fTime) +{ + int i; + + // erase the time + for(i=2; i<5; i++) { + digit[i].val = -1; + digit[i].type = DIGIT_TYPE_NORMAL; + } + + // draw time display + if (fTime == 0.0) { + // zero time is displayed as '00' + digit[2].val = -1; + digit[3].val = 0; + digit[4].val = 0; + } + else if (fTime > 0.0) { + + int nTime = (int)(fTime + .1); // add .1 for rounding error + + // draw 10s place + if ((nTime/10) != 0){ + digit[2].val = nTime/10; + } + else { + digit[2].val = -1; + } + + // draw 1s place (and decimal) + digit[3].val = nTime%10; + digit[3].type = DIGIT_TYPE_FLOAT; + + // draw fractional portion + char lpszTime[16]; + sprintf(lpszTime, "%.01f", fTime); + for (int i=0; lpszTime[i]; i++){ + if (lpszTime[i] == '.'){ + digit[4].val = lpszTime[i+1] - '0'; + break; + } + } + } +} + +void Football_DrawYard(int nYard) +{ + int sign; + int val, idx; + + // convert display to proper format + if (nYard >= 50){ + sign = 1; + val = 100 - nYard; + } else { + sign = -1; + val = nYard; + } + + // draw yard + idx = 2; + + if (sign == 1){ + // draw direction on left + digit[idx].val = 1; + digit[idx].type = DIGIT_TYPE_SPECIAL; + idx++; + } + + // draw 10s place + digit[idx].val = val/10; + digit[idx].type = DIGIT_TYPE_NORMAL; + idx++; + + digit[idx].val = val%10; + digit[idx].type = DIGIT_TYPE_NORMAL; + idx++; + + if (sign == -1){ + // draw direction on right + digit[idx].val = 0; + digit[idx].type = DIGIT_TYPE_SPECIAL; + } +} + +BOOL Football_GetInputKICK(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football_GetInputSTATUS(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputPLUS()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football_GetInputSCORE(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputMINUS()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football_GetInputRUN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT() + || Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football_TestForMovement() +{ + // check the keys + if (Platform_GetInputRIGHT() + || Platform_GetInputLEFT() + || Platform_GetInputUP() + || Platform_GetInputDOWN()) + { + return TRUE; + } + + return FALSE; +} + +void Football_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} diff --git a/source/platform/Platform_football.h b/source/platform/Platform_football.h new file mode 100644 index 0000000..952f673 --- /dev/null +++ b/source/platform/Platform_football.h @@ -0,0 +1,83 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_FOOTBALL_H__ +#define __PLATFORM_FOOTBALL_H__ +// [general] +#define football_digit_spacing 12 +#define football_digit_x 56 +#define football_digit_y 47 +#define football_digit_w 8 +#define football_digit_h 9 +#define football_blip_xspacing 2085 +#define football_blip_yspacing 1600 +#define football_blip_x 35 +#define football_blip_y 87 +#define football_power_off_x 82 +#define football_power_off_y 281 +#define football_pro_1_x 82 +#define football_pro_1_y 281 +#define football_pro_2_x 82 +#define football_pro_2_y 281 + +// interface that the platform must provide for this game + +// functions exported to the game context +void Football_Init(); +void Football_Help(); +void Football_DeInit(); +void Football_Paint(); +void Football_ClearScreen(); +void Football_PlaySound(int nSound, unsigned int nFlags); +void Football_StopSound(); +void Football_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void Football_DrawBlip(int nBright, int x, int y); +void Football_DrawScores(int nHScore, int nVScore); +void Football_DrawDown(int nDown, int nYards); +void Football_DrawTime(float fTime); +void Football_DrawYard(int nYard); + +BOOL Football_GetInputRUN(BOOL *pChange); +BOOL Football_GetInputUP(BOOL *pChange); +BOOL Football_GetInputDOWN(BOOL *pChange); +BOOL Football_GetInputKICK(BOOL *pChange); +BOOL Football_GetInputSTATUS(BOOL *pChange); +BOOL Football_GetInputSCORE(BOOL *pChange); +BOOL Football_TestForMovement(); + +#endif diff --git a/source/platform/Platform_football2.c b/source/platform/Platform_football2.c new file mode 100644 index 0000000..bc4626e --- /dev/null +++ b/source/platform/Platform_football2.c @@ -0,0 +1,638 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "football2.h" +#include "football2_screen_png.h" +#include "football2_poweroff_png.h" +#include "football2_pro1_png.h" +#include "football2_pro2_png.h" +#include "football2_chargestart_raw.h" +#include "football2_charge_raw.h" +#include "football2_tick_raw.h" +#include "football2_runback_raw.h" +#include "football2_firstdown_raw.h" +#include "football2_endplay_raw.h" +#include "football2_endpossession_raw.h" +#include "football2_endquarter_raw.h" +#include "football2_touchdown_raw.h" +#include "football2_safety_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpPro1; +static GRRLIB_texImg *bmpPro2; + +static Sound_t tcWaveRes[10]; +static Blip_t blip[FOOTBALL2_BLIP_COLUMNS][FOOTBALL2_BLIP_ROWS]; +static Digit_t digit[7] = { + {football2_digit_x, football2_digit_y, -1}, + {football2_digit_x + football2_digit_spacing, football2_digit_y, -1, -1}, + {football2_digit_x + (4 * football2_digit_spacing), football2_digit_y, -1, -1}, + {football2_digit_x + (5 * football2_digit_spacing), football2_digit_y, -1, -1}, + {football2_digit_x + (6 * football2_digit_spacing), football2_digit_y, -1, -1}, + {football2_digit_x + (9 * football2_digit_spacing), football2_digit_y, -1, -1}, + {football2_digit_x + (10 * football2_digit_spacing), football2_digit_y, -1, -1} +}; + +static Help_t help[] = { + { WK_2, { 72, 230} }, + { WK_1, { 15, 267} }, + { WK_MINUS, { 15, 230} }, + { WK_PLUS, { 15, 192} }, + { WK_BLR, { 91, 253 } }, + { WK_DPAD, { 163, 225} } +}; +//---------------------------------------------------------------------------- +// +// +void Football2_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void Football2_Init() +{ + int x, y; + + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], football2_chargestart_raw, football2_chargestart_raw_size, 865 ); + Sound_set(&tcWaveRes[1], football2_charge_raw, football2_charge_raw_size, 946 ); + Sound_set(&tcWaveRes[2], football2_tick_raw, football2_tick_raw_size, 12 ); + Sound_set(&tcWaveRes[3], football2_runback_raw, football2_runback_raw_size, 260 ); + Sound_set(&tcWaveRes[4], football2_firstdown_raw, football2_firstdown_raw_size, 138 ); + Sound_set(&tcWaveRes[5], football2_endplay_raw, football2_endplay_raw_size, 334 ); + Sound_set(&tcWaveRes[6], football2_endpossession_raw, football2_endpossession_raw_size, 700 ); + Sound_set(&tcWaveRes[7], football2_endquarter_raw, football2_endquarter_raw_size, 995 ); + Sound_set(&tcWaveRes[8], football2_touchdown_raw, football2_touchdown_raw_size, 2566 ); + Sound_set(&tcWaveRes[9], football2_safety_raw, football2_safety_raw_size, 726 ); + + // load images + bmpScreen = GRRLIB_LoadTexture(football2_screen_png); + + // set up the power switch images + bmpPowerOff = GRRLIB_LoadTexture(football2_poweroff_png); + bmpPro1 = GRRLIB_LoadTexture(football2_pro1_png); + bmpPro2 = GRRLIB_LoadTexture(football2_pro2_png); + + for (y = 0; y < FOOTBALL2_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL2_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)football2_blip_xspacing/100)) + football2_blip_x); + pblip->y = (int)((y * ((float)football2_blip_yspacing/100)) + football2_blip_y); + pblip->status = -1; + } + } + + // clean digit + for (x=0; x<7; x++) { + digit[x].val = -1; + digit[x].type = DIGIT_TYPE_NORMAL; + } + + PlatformSetInput(0); + // turn on the game + Football2_SetSkill(0); + Football2_PowerOn(); + + bInited = TRUE; + +} + +void Football2_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPro1); + GRRLIB_FreeTexture(bmpPro2); + bInited = FALSE; +} + +void Football2_Paint() +{ + int x, y; + BOOL power = Football2_GetPower(); + BOOL skill = Football2_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_OFF12); + if(power) { + if(p_switch == -1) { + if(skill == 0) + Football2_PowerOff(); + if(skill == 1) { + Football2_PowerOn(); + Football2_SetSkill(0); + } + } + if(p_switch == 1) { + if(skill == 0) { + Football2_PowerOn(); + Football2_SetSkill(1); + } + } + } + else { + if(p_switch == 1) { + Football2_PowerOn(); + Football2_SetSkill(0); + } + } +// if (gMainWndP == NULL){ return; } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power){ + if (skill == 0){ + GRRLIB_DrawImg(realx(football2_pro_1_x), realy(football2_pro_1_y), bmpPro1, 0, 1, 1, 0xFFFFFFFF); + } else { + GRRLIB_DrawImg(realx(football2_pro_2_x), realy(football2_pro_2_y), bmpPro2, 0, 1, 1, 0xFFFFFFFF); + } + + for (y = 0; y < FOOTBALL2_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL2_BLIP_COLUMNS; x++){ + if(blip[x][y].status != -1) + draw_oblip(blip[x][y].x, blip[x][y].y, blip[x][y].status); + } + } + for(x = 0; x < 7; x++) { + draw_digit_f(digit[x].x, digit[x].y, digit[x].val, digit[x].type); + } + } + else { + GRRLIB_DrawImg(realx(football2_power_off_x), realy(football2_power_off_y), bmpPowerOff, 0, 1, 1, 0xFFFFFFFF); + } + +} + +void Football2_ClearScreen() +{ + int x, y; + + Platform_StartDraw(); + + // erase the blips + for (y = 0; y < FOOTBALL2_BLIP_ROWS; y++){ + for (x = 0; x < FOOTBALL2_BLIP_COLUMNS; x++){ + Football2_DrawBlip(BLIP_OFF, x, y); + } + } + // erase the stat display + Football2_DrawScores(-1, -1); + Football2_DrawTime(-1); + + Platform_EndDraw(); +} + +void Football2_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void Football2_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + +//---------------------------------------------------------------------------- +// local fcn's +// + +void Football2_DrawBlip(int nBright, int x, int y) +{ + Blip_t *pblip = &blip[x][y]; + + switch(nBright){ + case BLIP_OFF: + pblip->status = -1; + break; + case BLIP_DIM: + pblip->status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + pblip->status = BLIP_TYPE_BRIGHT; + break; + } +} + +void Football2_DrawScores(int nHScore, int nVScore) +{ + // draw home team score + if (nHScore == -1){ + // erase the time + digit[0].val = -1; + digit[0].type = DIGIT_TYPE_NORMAL; + digit[1].val = -1; + digit[1].type = DIGIT_TYPE_NORMAL; + } else { + + // draw 10s place + if ((nHScore/10) != 0){ + digit[0].val = nHScore/10; + } else { + digit[0].val = -1; + } + digit[0].type = DIGIT_TYPE_NORMAL; + + // draw 1s place + digit[1].val = nHScore%10; + digit[1].type = DIGIT_TYPE_NORMAL; + } + + // draw visitor team score + if (nVScore == -1){ + // erase the time + digit[5].val = -1; + digit[5].type = DIGIT_TYPE_NORMAL; + digit[6].val = -1; + digit[6].type = DIGIT_TYPE_NORMAL; + } else { + // draw 10s place + if ((nVScore/10) != 0){ + digit[5].val = nVScore/10; + } else { + digit[5].val = -1; + } + digit[5].type = DIGIT_TYPE_NORMAL; + // draw 1s place + digit[6].val = nVScore%10; + digit[6].type = DIGIT_TYPE_NORMAL; + } +} + +void Football2_DrawDown(int nDown, int nYards) +{ + // draw downs + if (nDown == -1){ + // erase the down + digit[0].val = -1; + digit[0].type = DIGIT_TYPE_NORMAL; + digit[1].val = -1; + digit[1].type = DIGIT_TYPE_NORMAL; + } else { + ++nDown; + + // draw 10s place + if (nDown >= 10){ + digit[0].val = nDown/10; + } else { + digit[0].val = -1; + } + digit[0].type = DIGIT_TYPE_NORMAL; + + // draw 1s place + digit[1].val = nDown%10; + digit[1].type = DIGIT_TYPE_NORMAL; + } + + // draw yards + if (nYards <= 0){ + // erase the yards + digit[5].val = -1; + digit[5].type = DIGIT_TYPE_NORMAL; + digit[6].val = -1; + digit[6].type = DIGIT_TYPE_NORMAL; + } else { + // draw 10s place + if (nYards >= 10){ + digit[5].val = nYards/10; + } else { + digit[5].val = -1; + } + digit[5].type = DIGIT_TYPE_NORMAL; + + // draw 1s place + digit[6].val = nYards%10; + digit[6].type = DIGIT_TYPE_NORMAL; + } +} + +void Football2_DrawTime(float fTime) +{ + int i; + + // erase the time + for(i=2; i<5; i++) { + digit[i].val = -1; + digit[i].type = DIGIT_TYPE_NORMAL; + } + + // draw time display + if (fTime == 0.0) { + // zero time is displayed as '00' + digit[2].val = -1; + digit[3].val = 0; + digit[4].val = 0; + } + else if (fTime > 0.0) { + + int nTime = (int)(fTime + .1); // add .1 for rounding error + + // draw 10s place + if ((nTime/10) != 0){ + digit[2].val = nTime/10; + } + else { + digit[2].val = -1; + } + + // draw 1s place (and decimal) + digit[3].val = nTime%10; + digit[3].type = DIGIT_TYPE_FLOAT; + + // draw fractional portion + char lpszTime[16]; + sprintf(lpszTime, "%.01f", fTime); + for (int i=0; lpszTime[i]; i++){ + if (lpszTime[i] == '.'){ + digit[4].val = lpszTime[i+1] - '0'; + break; + } + } + } +} + +void Football2_DrawYard(int nYard) +{ + static int lastsign = 1; + int sign; + int val, idx; + + // convert display to proper format + if (nYard > 50){ + sign = 1; + lastsign = sign; + val = 100 - nYard; + } else if (nYard < 50){ + sign = -1; + lastsign = sign; + val = nYard; + } else { + // if ball is on the 50 yardline, use sign from last time + sign = lastsign; + val = nYard; + } + + // draw yard + idx = 2; + + if (sign == 1){ + // draw direction on left + digit[idx].val = 1; + digit[idx].type = DIGIT_TYPE_SPECIAL; + idx++; + } + + // draw 10s place + digit[idx].val = val/10; + digit[idx].type = DIGIT_TYPE_NORMAL; + idx++; + + digit[idx].val = val%10; + digit[idx].type = DIGIT_TYPE_NORMAL; + idx++; + + if (sign == -1){ + // draw direction on right + digit[idx].val = 0; + digit[idx].type = DIGIT_TYPE_SPECIAL; + } +} + +BOOL Football2_GetInputKICK(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput1()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputSTATUS(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputMINUS()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputSCORE(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputPLUS()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputPASS(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Football2_TestForMovement() +{ + // check the keys + if (Platform_GetInputLEFT() + || Platform_GetInputUP() + || Platform_GetInputRIGHT() + || Platform_GetInputDOWN()) + { + return TRUE; + } + + return FALSE; +} + +void Football2_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_football2.h b/source/platform/Platform_football2.h new file mode 100644 index 0000000..15a8588 --- /dev/null +++ b/source/platform/Platform_football2.h @@ -0,0 +1,85 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __PLATFORM_FOOTBALL2_H__ +#define __PLATFORM_FOOTBALL2_H__ + +// [general] +#define football2_digit_spacing 12 +#define football2_digit_x 57 +#define football2_digit_y 44 +#define football2_digit_w 8 +#define football2_digit_h 9 +#define football2_blip_xspacing 1925 +#define football2_blip_yspacing 1900 +#define football2_blip_x 31 +#define football2_blip_y 93 +#define football2_power_off_x 91 +#define football2_power_off_y 295 +#define football2_pro_1_x 91 +#define football2_pro_1_y 295 +#define football2_pro_2_x 91 +#define football2_pro_2_y 295 + +// interface that the platform must provide for this game + +// functions exported to the game context +void Football2_Init(); +void Football2_Help(); +void Football2_DeInit(); +void Football2_Paint(); +void Football2_ClearScreen(); +void Football2_PlaySound(int nSound, unsigned int nFlags); +void Football2_StopSound(); +void Football2_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void Football2_DrawBlip(int nBright, int x, int y); +void Football2_DrawScores(int nHScore, int nVScore); +void Football2_DrawDown(int nDown, int nYards); +void Football2_DrawTime(float fTime); +void Football2_DrawYard(int nYard); + +BOOL Football2_GetInputLEFT(BOOL *pChange); +BOOL Football2_GetInputUP(BOOL *pChange); +BOOL Football2_GetInputRIGHT(BOOL *pChange); +BOOL Football2_GetInputDOWN(BOOL *pChange); +BOOL Football2_GetInputKICK(BOOL *pChange); +BOOL Football2_GetInputPASS(BOOL *pChange); +BOOL Football2_GetInputSTATUS(BOOL *pChange); +BOOL Football2_GetInputSCORE(BOOL *pChange); +BOOL Football2_TestForMovement(); + +#endif diff --git a/source/platform/Platform_hockey.c b/source/platform/Platform_hockey.c new file mode 100644 index 0000000..a7b755e --- /dev/null +++ b/source/platform/Platform_hockey.c @@ -0,0 +1,371 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "hockey.h" +#include "hockey_screen_png.h" +#include "hockey_tick_raw.h" +#include "hockey_deflect_raw.h" +#include "hockey_bump_raw.h" +#include "hockey_poke_raw.h" +#include "hockey_score_raw.h" +#include "hockey_penalty_raw.h" +#include "hockey_steal_raw.h" +#include "hockey_endperiod_raw.h" +#include "hockey_endgame_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; + +static Sound_t tcWaveRes[9]; +static Blip_t blip[HOCKEY_BLIP_COLUMNS][HOCKEY_BLIP_ROWS]; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, { 181, 243} }, + { WK_BLR, { 24, 286 } }, + { WK_DPAD, { 104, 252} } +}; +//---------------------------------------------------------------------------- +// +// +void Hockey_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void Hockey_Init() +{ + int x, y; + + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], hockey_tick_raw, hockey_tick_raw_size, 14 ); + Sound_set(&tcWaveRes[1], hockey_deflect_raw, hockey_deflect_raw_size, 16 ); + Sound_set(&tcWaveRes[2], hockey_bump_raw, hockey_bump_raw_size, 35 ); + Sound_set(&tcWaveRes[3], hockey_poke_raw, hockey_poke_raw_size, 57 ); + Sound_set(&tcWaveRes[4], hockey_score_raw, hockey_score_raw_size, 1575 ); + Sound_set(&tcWaveRes[5], hockey_penalty_raw, hockey_penalty_raw_size, 1196 ); + Sound_set(&tcWaveRes[6], hockey_steal_raw, hockey_steal_raw_size, 531 ); + Sound_set(&tcWaveRes[7], hockey_endperiod_raw, hockey_endperiod_raw_size, 1205 ); + Sound_set(&tcWaveRes[8], hockey_endgame_raw, hockey_endgame_raw_size, 2382 ); + + // load images + bmpScreen = GRRLIB_LoadTexture(hockey_screen_png); + + // set blips + for (y = 0; y < HOCKEY_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEY_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)hockey_blip_xspacing/100)) + hockey_blip_x); + if(y == 0) + pblip->y = (int)(hockey_blip_y - ((hockey_blip_yspacing/100)/2)); + else + pblip->y = (int)(((y - 1) * ((float)hockey_blip_yspacing/100)) + hockey_blip_y); + pblip->status = -1; + } + } + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = hockey_digit_x + x * hockey_digit_spacing; + digit[x].y = hockey_digit_y; + } + + PlatformSetInput(0); + // turn on the game + Hockey_SetSkill(0); + Hockey_PowerOn(); + + bInited = TRUE; +} + +void Hockey_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + bInited = FALSE; +} + +void Hockey_Paint() +{ + int x, y; + BOOL power = Hockey_GetPower(); + BOOL skill = Hockey_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_1OFF2); + if(p_switch == -1) { + if(!power) { + Hockey_PowerOn(); + Hockey_SetSkill(0); + } + else if(power && skill == 1) { + Hockey_PowerOff(); + } + } + else if(p_switch == 1) { + if(!power) { + Hockey_PowerOn(); + Hockey_SetSkill(1); + } + else if(power && skill == 0) { + Hockey_PowerOff(); + } + } + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power){ + if (skill == 0){ + draw_poweroff_a(hockey_pro_1_x, hockey_pro_1_y, POWER_POS_MODE1); + } else { + draw_poweroff_a(hockey_pro_2_x, hockey_pro_2_y, POWER_POS_MODE2); + } + + for (y = 0; y < HOCKEY_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEY_BLIP_COLUMNS; x++){ + if(blip[x][y].status != -1) + draw_vblip(blip[x][y].x, blip[x][y].y, blip[x][y].status); + } + } + + for(x = 0; x < 2; x++) + draw_digit(digit[x].x, digit[x].y, digit[x].val); + } + else { + draw_poweroff_a(hockey_power_off_x, hockey_power_off_y, POWER_POS_OFF); + } +} + +void Hockey_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < HOCKEY_BLIP_ROWS; y++){ + for (int x = 0; x < HOCKEY_BLIP_COLUMNS; x++){ + Hockey_DrawBlip(BLIP_OFF, x, y); + } + } + + // erase the stat display + Hockey_DrawStat(-1); + + Platform_EndDraw(); +} + +void Hockey_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void Hockey_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void Hockey_DrawBlip(int nBright, int x, int y) +{ + int new_status; + + switch(nBright){ + case BLIP_DIM: + new_status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + new_status = BLIP_TYPE_BRIGHT; + break; + case BLIP_OFF: + default: + new_status = -1; + break; + } + blip[x][y].status = new_status; +} + +void Hockey_DrawStat(int nStat) +{ + if (nStat == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + digit[0].val = nStat/10; + // draw 1s place + digit[1].val = nStat%10; + } +} + +BOOL Hockey_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Hockey_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Hockey_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Hockey_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Hockey_GetInputTHROW(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Hockey_TestForMovement() +{ + // check the keys + if (Platform_GetInputLEFT() + || Platform_GetInputUP() + || Platform_GetInputRIGHT() + || Platform_GetInputDOWN() + || Platform_GetInput2()) + { + return TRUE; + } + + return FALSE; +} + +void Hockey_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_hockey.h b/source/platform/Platform_hockey.h new file mode 100644 index 0000000..4119b67 --- /dev/null +++ b/source/platform/Platform_hockey.h @@ -0,0 +1,78 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __PLATFORM_HOCKEY_H__ +#define __PLATFORM_HOCKEY_H__ +// [general] +#define hockey_digit_spacing 12 +#define hockey_digit_x 112 +#define hockey_digit_y 200 +#define hockey_digit_w 8 +#define hockey_digit_h 9 +#define hockey_blip_xspacing 3950 +#define hockey_blip_yspacing 4000 +#define hockey_blip_x 40 +#define hockey_blip_y 50 +#define hockey_power_off_x 27 +#define hockey_power_off_y 285 +#define hockey_pro_1_x 27 +#define hockey_pro_1_y 285 +#define hockey_pro_2_x 27 +#define hockey_pro_2_y 285 + +// interface that the platform must provide for this game + +// functions exported to the game context +void Hockey_Init(); +void Hockey_Help(); +void Hockey_DeInit(); +void Hockey_Paint(); +void Hockey_ClearScreen(); +void Hockey_PlaySound(int nSound, unsigned int nFlags); +void Hockey_StopSound(); +void Hockey_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void Hockey_DrawBlip(int nBright, int x, int y); +void Hockey_DrawStat(int nStat); + +BOOL Hockey_GetInputLEFT(BOOL *pChange); +BOOL Hockey_GetInputUP(BOOL *pChange); +BOOL Hockey_GetInputRIGHT(BOOL *pChange); +BOOL Hockey_GetInputDOWN(BOOL *pChange); +BOOL Hockey_GetInputTHROW(BOOL *pChange); +BOOL Hockey_TestForMovement(); + +#endif diff --git a/source/platform/Platform_hockeyca.c b/source/platform/Platform_hockeyca.c new file mode 100644 index 0000000..b333ece --- /dev/null +++ b/source/platform/Platform_hockeyca.c @@ -0,0 +1,397 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "hockeyca.h" +#include "hockeyca_screen_png.h" +#include "hockeyca_tick_raw.h" +#include "hockeyca_bounce_raw.h" +#include "hockeyca_score_raw.h" +#include "hockeyca_endplay_raw.h" +#include "hockeyca_endperiod_raw.h" +#include "hockeyca_endgame_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; + +static Sound_t tcWaveRes[6]; +static Blip_t blip[HOCKEYCA_BLIP_COLUMNS][HOCKEYCA_BLIP_ROWS]; +static Blip_t goal; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, { 181, 243} }, + { WK_BLR, { 25, 286 } }, + { WK_DPAD, { 104, 251} } +}; +//---------------------------------------------------------------------------- +// +// +void HockeyCa_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void HockeyCa_Init() +{ + int x, y; + + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], hockeyca_tick_raw, hockeyca_tick_raw_size, 13 ); + Sound_set(&tcWaveRes[1], hockeyca_bounce_raw, hockeyca_bounce_raw_size, 33 ); + Sound_set(&tcWaveRes[2], hockeyca_score_raw, hockeyca_score_raw_size, 3307 ); + Sound_set(&tcWaveRes[3], hockeyca_endplay_raw, hockeyca_endplay_raw_size, 762 ); + Sound_set(&tcWaveRes[4], hockeyca_endperiod_raw, hockeyca_endperiod_raw_size, 1654 ); + Sound_set(&tcWaveRes[5], hockeyca_endgame_raw, hockeyca_endgame_raw_size, 2543 ); + + // load images + bmpScreen = GRRLIB_LoadTexture(hockeyca_screen_png); + + // set blips + for (y = 0; y < HOCKEYCA_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEYCA_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)hockeyca_blip_xspacing/100)) + hockeyca_blip_x); + pblip->y = (int)((y * ((float)hockeyca_blip_yspacing/100)) + hockeyca_blip_y); + pblip->status = -1; + } + } + goal.x = hockeyca_goal_x; + goal.y = hockeyca_goal_y; + goal.status = -1; + + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = hockeyca_digit_x + x * hockeyca_digit_spacing; + digit[x].y = hockeyca_digit_y; + } + PlatformSetInput(0); + // turn on the game + HockeyCa_SetSkill(0); + HockeyCa_PowerOn(); + + bInited = TRUE; +} + +void HockeyCa_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + bInited = FALSE; +} + +void HockeyCa_Paint() +{ + int x, y; + BOOL power = HockeyCa_GetPower(); + BOOL skill = HockeyCa_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_1OFF2); + if(p_switch == -1) { + if(!power) { + HockeyCa_PowerOn(); + HockeyCa_SetSkill(0); + } + else if(power && skill == 1) { + HockeyCa_PowerOff(); + } + } + else if(p_switch == 1) { + if(!power) { + HockeyCa_PowerOn(); + HockeyCa_SetSkill(1); + } + else if(power && skill == 0) { + HockeyCa_PowerOff(); + } + } + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power){ + if (skill == 0){ + draw_poweroff_a(hockeyca_pro_1_x, hockeyca_pro_1_y, POWER_POS_MODE1); + } else { + draw_poweroff_a(hockeyca_pro_2_x, hockeyca_pro_2_y, POWER_POS_MODE2); + } + + for (y = 0; y < HOCKEYCA_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEYCA_BLIP_COLUMNS; x++){ + if(blip[x][y].status != -1) + draw_vblip(blip[x][y].x, blip[x][y].y, blip[x][y].status); + } + } + + if(goal.status != -1) + draw_vblip(goal.x, goal.y, goal.status); + + for(x = 0; x < sizeof(digit)/sizeof(*digit); x++) + draw_digit(digit[x].x, digit[x].y, digit[x].val); + } + else { + draw_poweroff_a(hockeyca_power_off_x, hockeyca_power_off_y, POWER_POS_OFF); + } +} + +void HockeyCa_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < HOCKEYCA_BLIP_ROWS; y++){ + for (int x = 0; x < HOCKEYCA_BLIP_COLUMNS; x++){ + HockeyCa_DrawBlip(BLIP_OFF, x, y); + } + } + HockeyCa_DrawGoal(FALSE); + + // erase the stat display + Platform_EndDraw(); +} + +void HockeyCa_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void HockeyCa_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void HockeyCa_DrawBlip(int nBright, int x, int y) +{ + int new_status; + + switch(nBright){ + case BLIP_DIM: + new_status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + new_status = BLIP_TYPE_BRIGHT; + break; + case BLIP_DIMFLICKER: + new_status = BLIP_TYPE_FLICKER; + break; + case BLIP_OFF: + default: + new_status = -1; + break; + } + blip[x][y].status = new_status; +} + +void HockeyCa_DrawStat(int nStat) +{ + if (nStat == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + digit[0].val = nStat/10; + // draw 1s place + digit[1].val = nStat%10; + } +} + +void HockeyCa_DrawGoal(BOOL bBasket) +{ + Platform_StartDraw(); + + if (bBasket) + { + int x, y; + + // erase the blips + for (y = 0; y < HOCKEYCA_BLIP_ROWS; y++){ + for (x = 0; x < HOCKEYCA_BLIP_COLUMNS; x++){ + HockeyCa_DrawBlip(BLIP_OFF, x, y); + } + } + // draw the basket + goal.status = BLIP_TYPE_BRIGHT; + } + else + { + // erase the goal + goal.status = -1; + } + + Platform_EndDraw(); +} + +BOOL HockeyCa_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL HockeyCa_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL HockeyCa_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL HockeyCa_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL HockeyCa_GetInputTHROW(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL HockeyCa_TestForMovement() +{ + // check the keys + if (Platform_GetInputLEFT() + || Platform_GetInputUP() + || Platform_GetInputRIGHT() + || Platform_GetInputDOWN() + || Platform_GetInput2()) + { + return TRUE; + } + + return FALSE; +} + +void HockeyCa_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_hockeyca.h b/source/platform/Platform_hockeyca.h new file mode 100644 index 0000000..c270990 --- /dev/null +++ b/source/platform/Platform_hockeyca.h @@ -0,0 +1,82 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#ifndef __PLATFORM_HOCKEYCA_H__ +#define __PLATFORM_HOCKEYCA_H__ + +// [general] +#define hockeyca_digit_spacing 12 +#define hockeyca_digit_x 112 +#define hockeyca_digit_y 200 +#define hockeyca_digit_w 8 +#define hockeyca_digit_h 9 +#define hockeyca_blip_xspacing 3950 +#define hockeyca_blip_yspacing 3900 +#define hockeyca_blip_x 40 +#define hockeyca_blip_y 55 +#define hockeyca_power_off_x 27 +#define hockeyca_power_off_y 285 +#define hockeyca_pro_1_x 27 +#define hockeyca_pro_1_y 285 +#define hockeyca_pro_2_x 27 +#define hockeyca_pro_2_y 285 +#define hockeyca_goal_x 120 +#define hockeyca_goal_y 33 + +// interface that the platform must provide for this game + +// functions exported to the game context +void HockeyCa_Init(); +void HockeyCa_Help(); +void HockeyCa_DeInit(); +void HockeyCa_Paint(); +void HockeyCa_ClearScreen(); +void HockeyCa_PlaySound(int nSound, unsigned int nFlags); +void HockeyCa_StopSound(); +void HockeyCa_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void HockeyCa_DrawBlip(int nBright, int x, int y); +void HockeyCa_DrawStat(int nStat); +void HockeyCa_DrawGoal(BOOL bBasket); + +BOOL HockeyCa_GetInputLEFT(BOOL *pChange); +BOOL HockeyCa_GetInputUP(BOOL *pChange); +BOOL HockeyCa_GetInputRIGHT(BOOL *pChange); +BOOL HockeyCa_GetInputDOWN(BOOL *pChange); +BOOL HockeyCa_GetInputTHROW(BOOL *pChange); +BOOL HockeyCa_TestForMovement(); + +#endif diff --git a/source/platform/Platform_soccer.c b/source/platform/Platform_soccer.c new file mode 100644 index 0000000..ff26e24 --- /dev/null +++ b/source/platform/Platform_soccer.c @@ -0,0 +1,398 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "soccer.h" +#include "soccer_screen_png.h" +#include "soccer_tick_raw.h" +#include "soccer_bounce_raw.h" +#include "soccer_score_raw.h" +#include "soccer_endplay_raw.h" +#include "soccer_endperiod_raw.h" +#include "soccer_endgame_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; + +static Sound_t tcWaveRes[6]; +static Blip_t blip[SOCCER_BLIP_COLUMNS][SOCCER_BLIP_ROWS]; +static Blip_t goal; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, { 180, 243} }, + { WK_BLR, { 25, 285 } }, + { WK_DPAD, { 105, 252} } +}; +//---------------------------------------------------------------------------- +// +// +void Soccer_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void Soccer_Init() +{ + int x, y; + + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], soccer_tick_raw, soccer_tick_raw_size, 21 ); + Sound_set(&tcWaveRes[1], soccer_bounce_raw, soccer_bounce_raw_size, 47 ); + Sound_set(&tcWaveRes[2], soccer_score_raw, soccer_score_raw_size, 1637 ); + Sound_set(&tcWaveRes[3], soccer_endplay_raw, soccer_endplay_raw_size, 793 ); + Sound_set(&tcWaveRes[4], soccer_endperiod_raw, soccer_endperiod_raw_size, 1746 ); + Sound_set(&tcWaveRes[5], soccer_endgame_raw, soccer_endgame_raw_size, 2687 ); + + // load images + bmpScreen = GRRLIB_LoadTexture(soccer_screen_png); + + // set blips + for (y = 0; y < SOCCER_BLIP_ROWS; y++){ + for (x = 0; x < SOCCER_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)soccer_blip_xspacing/100)) + soccer_blip_x); + pblip->y = (int)((y * ((float)soccer_blip_yspacing/100)) + soccer_blip_y); + pblip->status = -1; + } + } + goal.x = soccer_goal_x; + goal.y = soccer_goal_y; + goal.status = -1; + + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = soccer_digit_x + x * soccer_digit_spacing; + digit[x].y = soccer_digit_y; + } + PlatformSetInput(0); + // turn on the game + Soccer_SetSkill(0); + Soccer_PowerOn(); + + bInited = TRUE; +} + +void Soccer_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + GRRLIB_FreeTexture(bmpScreen); + bInited = FALSE; +} + +void Soccer_Paint() +{ + int x, y; + BOOL power = Soccer_GetPower(); + BOOL skill = Soccer_GetSkill(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_1OFF2); + if(p_switch == -1) { + if(!power) { + Soccer_PowerOn(); + Soccer_SetSkill(0); + } + else if(power && skill == 1) { + Soccer_PowerOff(); + } + } + else if(p_switch == 1) { + if(!power) { + Soccer_PowerOn(); + Soccer_SetSkill(1); + } + else if(power && skill == 0) { + Soccer_PowerOff(); + } + } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power){ + if (skill == 0){ + draw_poweroff_a(soccer_power_off_x, soccer_power_off_y, POWER_POS_MODE1); + } else { + draw_poweroff_a(soccer_power_off_x, soccer_power_off_y, POWER_POS_MODE2); + } + for (y = 0; y < SOCCER_BLIP_ROWS; y++){ + for (x = 0; x < SOCCER_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + if(pblip->status != -1) + draw_vblip(pblip->x, pblip->y, pblip->status); + } + } + if(goal.status != -1) + draw_vblip(goal.x, goal.y, goal.status); + for(x = 0; x < sizeof(digit)/sizeof(*digit); x++) + draw_digit(digit[x].x, digit[x].y, digit[x].val); + } + else { + draw_poweroff_a(soccer_power_off_x, soccer_power_off_y, POWER_POS_OFF); + } +} + +void Soccer_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < SOCCER_BLIP_ROWS; y++){ + for (int x = 0; x < SOCCER_BLIP_COLUMNS; x++){ + Soccer_DrawBlip(BLIP_OFF, x, y); + } + } + + Soccer_DrawGoal(FALSE); + + // erase the stat display + Soccer_DrawStat(-1); + + Platform_EndDraw(); +} + +void Soccer_PlaySound(int nSound, unsigned int nFlags) +{ + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void Soccer_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void Soccer_DrawBlip(int nBright, int x, int y) +{ + Blip_t *pblip = &blip[x][y]; + + switch(nBright){ + case BLIP_DIM: + pblip->status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + pblip->status = BLIP_TYPE_BRIGHT; + break; + case BLIP_DIMFLICKER: + pblip->status = BLIP_TYPE_FLICKER; + break; + case BLIP_OFF: + default: + pblip->status = -1; + break; + } +} + +void Soccer_DrawStat(int nStat) +{ + if (nStat == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + digit[0].val = nStat/10; + // draw 1s place + digit[1].val = nStat%10; + } +} + +void Soccer_DrawGoal(BOOL bBasket) +{ + Platform_StartDraw(); + + if (bBasket) + { + int x, y; + + // erase the blips + for (y = 0; y < SOCCER_BLIP_ROWS; y++){ + for (x = 0; x < SOCCER_BLIP_COLUMNS; x++){ + Soccer_DrawBlip(BLIP_OFF, x, y); + } + } + // draw the goal + goal.status = BLIP_TYPE_BRIGHT; + } + else + { + // erase the goal + goal.status = -1; + } + + Platform_EndDraw(); +} + +BOOL Soccer_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Soccer_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Soccer_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Soccer_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Soccer_GetInputTHROW(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL Soccer_TestForMovement() +{ + // check the keys + if (Platform_GetInputLEFT() + || Platform_GetInputUP() + || Platform_GetInputRIGHT() + || Platform_GetInputDOWN() + || Platform_GetInput2()) + { + return TRUE; + } + + return FALSE; +} + +void Soccer_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_soccer.h b/source/platform/Platform_soccer.h new file mode 100644 index 0000000..77af926 --- /dev/null +++ b/source/platform/Platform_soccer.h @@ -0,0 +1,83 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_SOCCER_H__ +#define __PLATFORM_SOCCER_H__ + +// [general] +#define soccer_digit_spacing 12 +#define soccer_digit_x 112 +#define soccer_digit_y 194 +#define soccer_digit_w 8 +#define soccer_digit_h 9 +#define soccer_blip_xspacing 3950 +#define soccer_blip_yspacing 4000 +#define soccer_blip_x 41 +#define soccer_blip_y 46 +#define soccer_power_off_x 27 +#define soccer_power_off_y 285 +#define soccer_pro_1_x 27 +#define soccer_pro_1_y 285 +#define soccer_pro_2_x 27 +#define soccer_pro_2_y 285 +#define soccer_goal_x 120 +#define soccer_goal_y 27 + +// interface that the platform must provide for this game + +// functions exported to the game context +void Soccer_Init(); +void Soccer_Help(); +void Soccer_DeInit(); +void Soccer_Paint(); +void Soccer_ClearScreen(); +void Soccer_PlaySound(int nSound, unsigned int nFlags); +void Soccer_StopSound(); +void Soccer_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void Soccer_DrawBlip(int nBright, int x, int y); +void Soccer_DrawStat(int nStat); +void Soccer_DrawGoal(BOOL bBasket); + +BOOL Soccer_GetInputLEFT(BOOL *pChange); +BOOL Soccer_GetInputUP(BOOL *pChange); +BOOL Soccer_GetInputRIGHT(BOOL *pChange); +BOOL Soccer_GetInputDOWN(BOOL *pChange); +BOOL Soccer_GetInputTHROW(BOOL *pChange); +BOOL Soccer_TestForMovement(); + +#endif diff --git a/source/platform/Platform_spacealert.c b/source/platform/Platform_spacealert.c new file mode 100644 index 0000000..2eee114 --- /dev/null +++ b/source/platform/Platform_spacealert.c @@ -0,0 +1,376 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "spacealert.h" +#include "spacealert_screen_png.h" +#include "spacealert_poweron_png.h" +#include "spacealert_poweroff_png.h" +#include "spacealert_aimleft_png.h" +#include "spacealert_aimcenter_png.h" +#include "spacealert_aimright_png.h" +#include "spacealert_fire_raw.h" +#include "spacealert_hit_raw.h" +#include "spacealert_lose_raw.h" +#include "spacealert_win_raw.h" +#include "spacealert_raider_raw.h" + +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpPowerOn; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpAimLeft; +static GRRLIB_texImg *bmpAimCenter; +static GRRLIB_texImg *bmpAimRight; + +static int nStick = 1; + +static BOOL bRaiderSound = FALSE; +static BOOL bRaiderSoundPlaying = FALSE; + +static void StartRaiderSound(); +static void StopRaiderSound(); + +static Sound_t tcWaveRes[5]; +static Blip_t blip[SPACEALERT_BLIP_COLUMNS][SPACEALERT_BLIP_ROWS]; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, { 86, 122 } }, + { WK_BUD, { 88, 224 } }, + { WK_LR, { 156, 265 } } +}; +//---------------------------------------------------------------------------- +// +// +void SpaceAlert_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void SpaceAlert_Init() +{ + int x, y; + if (bInited) return; + + // Init sounds + Sound_set(&tcWaveRes[0], spacealert_fire_raw, spacealert_fire_raw_size, 109); + Sound_set(&tcWaveRes[1], spacealert_hit_raw, spacealert_hit_raw_size, 284); + Sound_set(&tcWaveRes[2], spacealert_lose_raw, spacealert_lose_raw_size, 1243); + Sound_set(&tcWaveRes[3], spacealert_win_raw, spacealert_win_raw_size, 850); + Sound_set(&tcWaveRes[4], spacealert_raider_raw, spacealert_raider_raw_size, 3902); + + // load images + bmpScreen = GRRLIB_LoadTexture(spacealert_screen_png); + bmpPowerOn = GRRLIB_LoadTexture(spacealert_poweron_png); + bmpPowerOff = GRRLIB_LoadTexture(spacealert_poweroff_png); + bmpAimLeft = GRRLIB_LoadTexture(spacealert_aimleft_png); + bmpAimCenter = GRRLIB_LoadTexture(spacealert_aimcenter_png); + bmpAimRight = GRRLIB_LoadTexture(spacealert_aimright_png); + + // set blips + for (y = 0; y < SPACEALERT_BLIP_ROWS; y++){ + for (x = 0; x < SPACEALERT_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)spacealert_blip_xspacing/100)) + spacealert_blip_x); + pblip->y = (int)((y * ((float)spacealert_blip_yspacing/100)) + spacealert_blip_y); + pblip->status = -1; + } + } + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = spacealert_digit_x + x * spacealert_digit_spacing; + digit[x].y = spacealert_digit_y; + } + PlatformSetInput(0); + // start with the game off + SpaceAlert_PowerOff(); + + bInited = TRUE; +} + +void SpaceAlert_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + bRaiderSoundPlaying = FALSE; + + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPowerOn); + GRRLIB_FreeTexture(bmpAimLeft); + GRRLIB_FreeTexture(bmpAimCenter); + GRRLIB_FreeTexture(bmpAimRight); + + bInited = FALSE; +} + +void SpaceAlert_Paint() +{ + int x, y; + BOOL power = SpaceAlert_GetPower(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_SWITCH); + if(p_switch == -1 && power == TRUE) { + SpaceAlert_PowerOff(); + } + if(p_switch == 1 && power == FALSE) { + SpaceAlert_PowerOn(); + } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power){ + GRRLIB_DrawImg(realx(spacealert_power_x), realy(spacealert_power_y), bmpPowerOn, 0, 1, 1, 0xFFFFFFFF); + + for (y = 0; y < SPACEALERT_BLIP_ROWS; y++){ + for (x = 0; x < SPACEALERT_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + if(pblip->status != -1) + draw_vblip(pblip->x, pblip->y, pblip->status); + } + } + // Draw points + for(x = 0; x < 2; x++) + draw_digit(digit[x].x, digit[x].y, digit[x].val); + // Draw stick + switch (nStick) + { + case 0: + GRRLIB_DrawImg(realx(spacealert_slider_x), realy(spacealert_slider_y), bmpAimLeft, 0, 1, 1, 0xFFFFFFFF); + break; + case 1: + GRRLIB_DrawImg(realx(spacealert_slider_x), realy(spacealert_slider_y), bmpAimCenter, 0, 1, 1, 0xFFFFFFFF); + break; + case 2: + GRRLIB_DrawImg(realx(spacealert_slider_x), realy(spacealert_slider_y), bmpAimRight, 0, 1, 1, 0xFFFFFFFF); + break; + } + } + else { + GRRLIB_DrawImg(realx(spacealert_power_x), realy(spacealert_power_y), bmpPowerOff, 0, 1, 1, 0xFFFFFFFF); + } + +} + +void SpaceAlert_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < SPACEALERT_BLIP_ROWS; y++){ + for (int x = 0; x < SPACEALERT_BLIP_COLUMNS; x++){ + SpaceAlert_DrawBlip(BLIP_OFF, x, y); + } + } + + // erase the score display + SpaceAlert_DrawScore(-1); + + Platform_EndDraw(); +} + +void SpaceAlert_PlaySound(int nSound, unsigned int nFlags) +{ + if ((nFlags & PLAYSOUNDFLAGS_PRIORITY) || bRaiderSoundPlaying) + { + // stop any playing sounds first + Platform_StopSound(); + } + + // this sound will cut off any looping sounds + // note this so we can restart them later + bRaiderSoundPlaying = FALSE; + + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void SpaceAlert_StopSound() +{ + bRaiderSoundPlaying = FALSE; + bRaiderSound = FALSE; + + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +static void StartRaiderSound() +{ + if (!bRaiderSoundPlaying) + { + + unsigned int nSoundFlags = PLAYSOUNDFLAGS_LOOP | PLAYSOUNDFLAGS_ASYNC; + Platform_PlaySound(&tcWaveRes[SPACEALERT_SOUND_RAIDER], nSoundFlags); + // mark the sound as playing + bRaiderSoundPlaying = TRUE; + } +} + +static void StopRaiderSound() +{ + if (bRaiderSoundPlaying) + { + Platform_StopSound(); + bRaiderSoundPlaying = FALSE; + } +} + +void SpaceAlert_PlayRaiderSound() +{ + if (!bRaiderSound) + { + bRaiderSound = TRUE; + StartRaiderSound(); + } +} + +void SpaceAlert_StopRaiderSound() +{ + if (bRaiderSound) + { + bRaiderSound = FALSE; + StopRaiderSound(); + } +} + +void SpaceAlert_DrawBlip(int nBright, int x, int y) +{ + switch(nBright){ + case BLIP_OFF: + blip[x][y].status = -1; + break; + case BLIP_DIM: + blip[x][y].status = BLIP_TYPE_NORMAL; + break; + case BLIP_BRIGHT: + blip[x][y].status = BLIP_TYPE_BRIGHT; + break; + } + + // update the looped raider sound + // this is not a good place for this + // should be in some sort of draw frame function + // maybe need to add that to the game structure + if (bRaiderSound){ + StartRaiderSound(); + } else { + StopRaiderSound(); + } + +} + +void SpaceAlert_DrawScore(int nScore) +{ + if (nScore == -1){ + // erase the display + digit[0].val = -1; + digit[1].val = -1; + } else { + // draw 10s place + digit[0].val = nScore/10; + // draw 1s place + digit[1].val = nScore%10; + } +} + +int SpaceAlert_GetInputSTICK() +{ + // check the keys + if (Platform_GetInputLEFT() + && !Platform_GetInputRIGHT()) + { + if (nStick != 0) + { + nStick = 0; + } + return nStick; + } + if (Platform_GetInputRIGHT() + && !Platform_GetInputLEFT()) + { + if (nStick != 2) + { + nStick = 2; + } + return nStick; + } + + if (nStick != 1) + { + nStick = 1; + } + return nStick; +} + +BOOL SpaceAlert_GetInputFIRE(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast) + { + if (pChange) + { + *pChange = TRUE; + } + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +void SpaceAlert_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + + diff --git a/source/platform/Platform_spacealert.h b/source/platform/Platform_spacealert.h new file mode 100644 index 0000000..2e31def --- /dev/null +++ b/source/platform/Platform_spacealert.h @@ -0,0 +1,78 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_SPACEALERT_H__ +#define __PLATFORM_SPACEALERT_H__ + +// [general] +#define spacealert_digit_spacing 12 +#define spacealert_digit_x 163 +#define spacealert_digit_y 86 +#define spacealert_digit_w 13 +#define spacealert_digit_h 14 +#define spacealert_blip_xspacing 1300 +#define spacealert_blip_yspacing 1600 +#define spacealert_blip_x 158 +#define spacealert_blip_y 117 +#define spacealert_slider_x 142 +#define spacealert_slider_y 271 +#define spacealert_power_x 87 +#define spacealert_power_y 231 +#define spacealert_kfire_x 73 +#define spacealert_kfire_y 148 + +// interface that the platform must provide for this game + +// functions exported to the game context +void SpaceAlert_Init(); +void SpaceAlert_Help(); +void SpaceAlert_DeInit(); +void SpaceAlert_Paint(); +void SpaceAlert_ClearScreen(); +void SpaceAlert_PlaySound(int nSound, unsigned int nFlags); +void SpaceAlert_StopSound(); +void SpaceAlert_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void SpaceAlert_PlayRaiderSound(); +void SpaceAlert_StopRaiderSound(); +void SpaceAlert_DrawBlip(int nBright, int x, int y); +void SpaceAlert_DrawScore(int nScore); + +int SpaceAlert_GetInputSTICK(); +BOOL SpaceAlert_GetInputFIRE(BOOL *pChange); + +#endif diff --git a/source/platform/Platform_subchase.c b/source/platform/Platform_subchase.c new file mode 100644 index 0000000..5f48905 --- /dev/null +++ b/source/platform/Platform_subchase.c @@ -0,0 +1,371 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include "subchase.h" +#include "subchase_screen_png.h" +#include "subchase_blipdim_png.h" +#include "subchase_blipbright_png.h" +#include "subchase_digits_png.h" +#include "subchase_poweroff_png.h" +#include "subchase_poweron_png.h" +#include "subchase_sonar_raw.h" +#include "subchase_charge_raw.h" +#include "subchase_hit_raw.h" +#include "subchase_sink_raw.h" + +#define DIGIT_W 24 +#define DIGIT_H 28 + +// images +static GRRLIB_texImg *bmpScreen; +static GRRLIB_texImg *bmpBlipDim; +static GRRLIB_texImg *bmpBlipBright; +static GRRLIB_texImg *bmpDigits; +static GRRLIB_texImg *bmpPowerOff; +static GRRLIB_texImg *bmpPowerOn; + +static Sound_t tcWaveRes[4]; +static Blip_t blip[SUBCHASE_BLIP_COLUMNS][SUBCHASE_BLIP_ROWS]; +static Stat_t digit[2]; +static Help_t help[] = { + { WK_2, {1, 115} }, + { WK_BUD, { 73, 242 } }, + { WK_DPAD, { 148, 257 } } +}; +//---------------------------------------------------------------------------- +// +// +void SubChase_Help() +{ + Platform_Help(help, sizeof(help)/sizeof(*help)); +} + +static BOOL bInited = FALSE; + +void SubChase_Init() +{ + int x, y; + + // Init sounds + Sound_set(&tcWaveRes[0], subchase_sonar_raw, subchase_sonar_raw_size, 119); + Sound_set(&tcWaveRes[1], subchase_charge_raw, subchase_charge_raw_size, 915); + Sound_set(&tcWaveRes[2], subchase_hit_raw, subchase_hit_raw_size, 1190); + Sound_set(&tcWaveRes[3], subchase_sink_raw, subchase_sink_raw_size, 1654); + + // load images + bmpScreen = GRRLIB_LoadTexture(subchase_screen_png); + bmpBlipDim = GRRLIB_LoadTexture(subchase_blipdim_png); + bmpBlipBright = GRRLIB_LoadTexture(subchase_blipbright_png); + bmpDigits = GRRLIB_LoadTexture(subchase_digits_png); + GRRLIB_InitTileSet(bmpDigits, DIGIT_W, DIGIT_H, 0); + + bmpPowerOff = GRRLIB_LoadTexture(subchase_poweroff_png); + bmpPowerOn = GRRLIB_LoadTexture(subchase_poweron_png); + + // set blips + for (y = 0; y < SUBCHASE_BLIP_ROWS; y++){ + for (x = 0; x < SUBCHASE_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + pblip->x = (int)((x * ((float)subchase_blip_xspacing/100)) + subchase_blip_x); + pblip->y = (int)((y * ((float)subchase_blip_yspacing/100)) + subchase_blip_y); + pblip->status = -1; + } + } + // set digits + for(x = 0; x < 2; x++) { + digit[x].x = subchase_digit_x + x * subchase_digit_spacing; + digit[x].y = subchase_digit_y; + } + + if (!bInited) + { + PlatformSetInput(0); + // turn game on + SubChase_PowerOn(); + + bInited = TRUE; + } +} + +void SubChase_DeInit() +{ + // stop all sounds... + Platform_StopSound(); + + GRRLIB_FreeTexture(bmpScreen); + GRRLIB_FreeTexture(bmpBlipDim); + GRRLIB_FreeTexture(bmpBlipBright); + GRRLIB_FreeTexture(bmpDigits); + GRRLIB_FreeTexture(bmpPowerOff); + GRRLIB_FreeTexture(bmpPowerOn); + + bInited = FALSE; +} + +void SubChase_Paint() +{ + int x, y; + BOOL power = SubChase_GetPower(); + int p_switch; + p_switch = Platform_GetPowerSwitch(ONOFF_SWITCH); + if(p_switch == -1 && power == TRUE) { + SubChase_PowerOff(); + } + if(p_switch == 1 && power == FALSE) { + SubChase_PowerOn(); + } + + // paint the backdrop + GRRLIB_DrawImg(realx(0), realy(0), bmpScreen, 0, 1, 1, 0xFFFFFFFF); + + // visualize the control states + if (power) + { + GRRLIB_DrawImg(realx(subchase_power_x), realy(subchase_power_y), bmpPowerOn, 0, 1, 1, 0xFFFFFFFF); + + for (y = 0; y < SUBCHASE_BLIP_ROWS; y++){ + for (x = 0; x < SUBCHASE_BLIP_COLUMNS; x++){ + Blip_t *pblip = &blip[x][y]; + + switch(pblip->status) { + case BLIP_DIM: + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlipDim, 0, 1, 1, 0xFFFFFFFF); + break; + case BLIP_BRIGHT: + GRRLIB_DrawImg(realx(pblip->x), realy(pblip->y), bmpBlipBright, 0, 1, 1, 0xFFFFFFFF); + break; + case BLIP_OFF: + default: + break; + } + } + } + + for(x = 0; x < 2; x++) { + GRRLIB_DrawTile(realx(digit[x].x), realy(digit[x].y), bmpDigits, 0, 1, 1, 0xFFFFFFFF, digit[x].val); + } + } + else + { + GRRLIB_DrawImg(realx(subchase_power_x), realy(subchase_power_y), bmpPowerOff, 0, 1, 1, 0xFFFFFFFF); + } +} + +void SubChase_ClearScreen() +{ + Platform_StartDraw(); + + // erase the blips + for (int y = 0; y < SUBCHASE_BLIP_ROWS; y++){ + for (int x = 0; x < SUBCHASE_BLIP_COLUMNS; x++){ + SubChase_DrawBlip(BLIP_OFF, x, y); + } + } + + Platform_EndDraw(); +} + +void SubChase_PlaySound(int nSound, unsigned int nFlags) +{ + if (nFlags & PLAYSOUNDFLAGS_PRIORITY) + { + // stop any playing sounds first + Platform_StopSound(); + } + + Platform_PlaySound(&tcWaveRes[nSound], nFlags); +} + +void SubChase_StopSound() +{ + // stop all sounds... + Platform_StopSound(); +} + + +//---------------------------------------------------------------------------- +// local fcn's +// + +void SubChase_DrawBlip(int nBright, int x, int y) +{ + switch(nBright){ + case BLIP_OFF: + blip[x][y].status = -1; + break; + case BLIP_DIM: + blip[x][y].status = BLIP_DIM; + break; + case BLIP_BRIGHT: + blip[x][y].status = BLIP_BRIGHT; + break; + } +} + +void SubChase_DrawScore(int nScore) +{ + if (nScore == -1){ + // erase the display + digit[0].val = 0; + digit[1].val = 0; + } else { + // draw 10s place + if (nScore >= 10){ + digit[0].val = (nScore/10) + 1; + } else { + digit[0].val = 0; + } + // draw 1s place + digit[1].val = (nScore%10) + 1; + } +} + +BOOL SubChase_GetInputFIRE(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInput2()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL SubChase_GetInputLEFT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputLEFT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL SubChase_GetInputUP(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputUP()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL SubChase_GetInputRIGHT(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputRIGHT()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +BOOL SubChase_GetInputDOWN(BOOL *pChange) +{ + static BOOL bLast = FALSE; + + if (pChange){ *pChange = FALSE; } + + // check the keys + if (Platform_GetInputDOWN()) + { + if (!bLast && pChange) + { + *pChange = TRUE; + } + bLast = TRUE; + return TRUE; + } + + bLast = FALSE; + + return FALSE; +} + +void SubChase_GetSize(int *w, int *h) +{ + *w = bmpScreen->w; + *h = bmpScreen->h; +} + diff --git a/source/platform/Platform_subchase.h b/source/platform/Platform_subchase.h new file mode 100644 index 0000000..cc08ae7 --- /dev/null +++ b/source/platform/Platform_subchase.h @@ -0,0 +1,107 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + + +#ifndef __PLATFORM_SUBCHASE_H__ +#define __PLATFORM_SUBCHASE_H__ +// [general] +#define subchase_digit_spacing 21 +#define subchase_digit_x 103 +#define subchase_digit_y 46 +#define subchase_digit_w 21 +#define subchase_digit_h 27 +#define subchase_blip_xspacing 2400 +#define subchase_blip_yspacing 3400 +#define subchase_blip_x 49 +#define subchase_blip_y 90 +#define subchase_power_x 42 +#define subchase_power_y 251 + +// [areas] +#define subchase_power_off_x 38 +#define subchase_power_off_y 268 +#define subchase_power_off_w 22 +#define subchase_power_off_h 16 +#define subchase_power_on_x 38 +#define subchase_power_on_y 252 +#define subchase_power_on_w 22 +#define subchase_power_on_h 16 +#define subchase_up_x 145 +#define subchase_up_y 227 +#define subchase_up_w 25 +#define subchase_up_h 22 +#define subchase_down_x 145 +#define subchase_down_y 274 +#define subchase_down_w 25 +#define subchase_down_h 22 +#define subchase_left_x 125 +#define subchase_left_y 249 +#define subchase_left_w 22 +#define subchase_left_h 25 +#define subchase_right_x 168 +#define subchase_right_y 249 +#define subchase_right_w 22 +#define subchase_right_h 25 +#define subchase_fire_x 0 +#define subchase_fire_y 0 +#define subchase_fire_w 0 +#define subchase_fire_h 0 + + +// interface that the platform must provide for this game + +// functions exported to the game context +void SubChase_Init(); +void SubChase_Help(); +void SubChase_DeInit(); +void SubChase_Paint(); +void SubChase_ClearScreen(); +void SubChase_PlaySound(int nSound, unsigned int nFlags); +void SubChase_StopSound(); +void SubChase_OnClick(int x, int y); +int SubChase_OnMouseMove(int x, int y); +void SubChase_GetSize(int *w, int *h); + +// "private" functions not exported to game context +void SubChase_DrawBlip(int nBright, int x, int y); +void SubChase_DrawScore(int nScore); + +int SubChase_GetInputLEFT(BOOL *pChange); +int SubChase_GetInputUP(BOOL *pChange); +int SubChase_GetInputRIGHT(BOOL *pChange); +int SubChase_GetInputDOWN(BOOL *pChange); +int SubChase_GetInputFIRE(BOOL *pChange); + +#endif diff --git a/source/platform/Random.c b/source/platform/Random.c new file mode 100644 index 0000000..a84c8b4 --- /dev/null +++ b/source/platform/Random.c @@ -0,0 +1,60 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +#include +#include + +static unsigned int seed = 0; + +void InitRandom() +{ + if(seed == 0) { + seed = time(NULL); + srandom(seed); + } +} + +void DeinitRandom() +{ + seed = 0; +} + +// return a random number between 0 and range +int Random(int nRange) +{ + return (int)(random() % nRange); +} + + diff --git a/source/platform/Random.h b/source/platform/Random.h new file mode 100644 index 0000000..1a4522a --- /dev/null +++ b/source/platform/Random.h @@ -0,0 +1,39 @@ +/* + +LEDhead +Copyright 2001, Peter Hirschberg +Author: Peter Hirschberg + +The current version of this SOURCE CODE as well as the official +versions of the LEDHEAD APPLICATION are available from my website +at: http://www.peterhirschberg.com + +Based on the handheld electronic games by Mattel Electronics. +All trademarks copyrighted by their respective owners. This +program is not affiliated or endorsed by Mattel Electronics. + +License agreement: + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (license.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Email : peter@peterhirschberg.com +Website : http://www.peterhirschberg.com + +*/ + +void InitRandom(); +void DeinitRandom(); +int Random(int nRange); + diff --git a/source/platform/help.c b/source/platform/help.c new file mode 100644 index 0000000..0f80f88 --- /dev/null +++ b/source/platform/help.c @@ -0,0 +1,75 @@ +/* + * LEDhead for Wii + * Copyright (C) 2017-2020 Nebiun + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "LED_Handled.h" +#include "Platform.h" +#include "WK1_png.h" +#include "WK2_png.h" +#include "WKA_png.h" +#include "WKB_png.h" +#include "WKBUD_png.h" +#include "WKBLR_png.h" +#include "WKPLUS_png.h" +#include "WKMINUS_png.h" +#include "WKHOME_png.h" +#include "WKDPAD_png.h" +#include "WKUD_png.h" +#include "WKLR_png.h" + +static GRRLIB_texImg *key_img[WK_NUMKEY]; + +static void _key_init(void) +{ + if(key_img[0] == NULL) { + key_img[WK_1] = GRRLIB_LoadTexture(WK1_png); + key_img[WK_2] = GRRLIB_LoadTexture(WK2_png); + key_img[WK_A] = GRRLIB_LoadTexture(WKA_png); + key_img[WK_B] = GRRLIB_LoadTexture(WKB_png); + key_img[WK_BUD] = GRRLIB_LoadTexture(WKBUD_png); + key_img[WK_BLR] = GRRLIB_LoadTexture(WKBLR_png); + key_img[WK_PLUS] = GRRLIB_LoadTexture(WKPLUS_png); + key_img[WK_MINUS] = GRRLIB_LoadTexture(WKMINUS_png); + key_img[WK_HOME] = GRRLIB_LoadTexture(WKHOME_png); + key_img[WK_DPAD] = GRRLIB_LoadTexture(WKDPAD_png); + key_img[WK_UD] = GRRLIB_LoadTexture(WKUD_png); + key_img[WK_LR] = GRRLIB_LoadTexture(WKLR_png); + } +} + +void Platform_Help(Help_t *vect, int n) +{ + int i; + if(key_img[0] == NULL) + _key_init(); + + for(i=0; i= WK_NUMKEY) + return; + + if(key_img[0] == NULL) + _key_init(); + + GRRLIB_DrawImg(x,y,key_img[val],0,1,1, 0xFFFFFFFF); +} diff --git a/source/power.c b/source/power.c new file mode 100644 index 0000000..f37fc9d --- /dev/null +++ b/source/power.c @@ -0,0 +1,52 @@ +/* + * LEDhead for Wii + * Copyright (C) 2017-2020 Nebiun + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "LED_Handled.h" +#include "poweroff_a_png.h" + +#define POWEROFF_H 8 +#define POWEROFF_W 48 + +int draw_poweroff_a(int x, int y, int val) +{ + static GRRLIB_texImg *power = NULL; + int idx; + + if(power == NULL) { + power = GRRLIB_LoadTexture(poweroff_a_png); + if(power == NULL) + return -1; + GRRLIB_InitTileSet(power, POWEROFF_W, POWEROFF_H, 0); + } + + switch(val) { + case POWER_POS_MODE1: + idx = 1; + break; + case POWER_POS_MODE2: + idx = 2; + break; + case POWER_POS_OFF: + default: + idx = 0; + break; + } + GRRLIB_DrawTile(realx(x), realy(y), power, 0, 1, 1, 0xFFFFFFFF, idx); + + return idx; +}