Integrate Aznable codebase

This commit is contained in:
jimmystones
2021-12-22 17:11:57 +00:00
parent 2aab758881
commit 8a93d6fdb2
169 changed files with 17233 additions and 2032 deletions

View File

@@ -1,25 +0,0 @@
SDCC=sdcc
CPU=z80
CODE=os
OBJ=os.rel
DATALOC=0xC000
all: $(CODE).bin
%.rel: %.c
$(SDCC) -m$(CPU) -c --data-loc $(DATALOC) $<
%.ihx: $(OBJ)
$(SDCC) -m$(CPU) --data-loc $(DATALOC) $(OBJ)
%.hex: %.ihx
mv $< $@
%.bin: %.hex
srec_cat $< -intel -o $@ -binary
disasm: $(CODE).bin
z80dasm -a -t -g 0 $<
clean:
rm -rf *~ *.asm *.ihx *.lk *.lst *.map *.noi *.rel *.sym *.hex *.bin

10
src/inputtest/.define Normal file
View File

@@ -0,0 +1,10 @@
//DISABLE_CPU
//DISABLE_SPRITES
//DISABLE_TILEMAP
//DISABLE_CHARMAP
//DEBUG_SPRITE_COLLISION
//DISABLE_STARS_1
//DISABLE_STARS_2
//DISABLE_STARS_3
//DISABLE_MUSIC
//DISABLE_SOUND

2
src/inputtest/Makefile Normal file
View File

@@ -0,0 +1,2 @@
DEFINES=-DPROJECT_NAME=inputtest
include ../shared/Makefile

132
src/inputtest/credits.c Normal file
View File

@@ -0,0 +1,132 @@
/*============================================================================
Aznable OS - Credits
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2022-01-05
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "../shared/ps2.h"
#include "../shared/sprite.h"
#include "../shared/music.h"
#include "../shared/tilemap.h"
#include "../shared/starfield.h"
#include "credits.h"
#include "inputtester_sys.h"
const char *credits_text = "CODE AND GFX_-_JIMMYSTONES___MUSIC_-_DARRIN CARDANI___TESTING_-_PORKCHOP EXPRESS_SORGELIG_M WALRUS___EXTRA THANKS_-_ALANSWX_SORGELIG___";
unsigned char credits_pos = 0;
unsigned short credits_entry_pos = (16 * 32);
void app_credits()
{
clear_chars(0);
clear_sprites();
clear_tilemap();
stop_music();
enable_starfield();
set_starfield_speed_x(0);
set_starfield_speed_y(-0.1f);
tilemap_offset_x = 0;
tilemap_offset_y = 0;
char credits_line[22];
credits_pos = 0;
while (1)
{
vblank = CHECK_BIT(input0, INPUT_VBLANK);
if (VBLANK_RISING)
{
if (tilemap_offset_y >= 16)
{
tilemap_offset_y -= 16;
update_tilemap_offset();
scroll_tilemap_up();
unsigned char d;
unsigned char c;
unsigned char credits_line_len = 0;
for (d = 0; d < 22; d++)
{
c = credits_text[credits_pos];
credits_pos++;
if (c == '_' || c == 0)
{
break;
}
else
{
credits_line[d] = c;
credits_line_len++;
}
if (credits_pos >= strlen(credits_text) - 1)
{
credits_pos = 0;
break;
}
}
signed char credits_line_pre = (22 - credits_line_len) / 2;
for (d = 0; d < 22; d++)
{
c = 0;
signed char i = d - credits_line_pre;
if (i >= 0 && i < credits_line_len)
{
c = (credits_line[i] != '-') ? (credits_line[i] - 45) : 1;
}
tilemapram[credits_entry_pos + d] = c;
}
}
else
{
update_tilemap_offset();
}
}
if (VBLANK_FALLING)
{
handle_ps2();
basic_input();
if (input_a || input_b || input_select || input_start)
{
break;
}
signed dir = 1;
tilemap_offset_y += 2;
if (input_up)
{
tilemap_offset_y += 4;
}
}
vblank_last = vblank;
}
clear_chars(0);
clear_sprites();
clear_tilemap();
stop_music();
disable_starfield();
state = defaultstate;
}

22
src/inputtest/credits.h Normal file
View File

@@ -0,0 +1,22 @@
/*============================================================================
Aznable OS - Credits
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2022-01-05
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
extern void app_credits();

View File

@@ -19,12 +19,11 @@
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "fader.h"
#include "inputtester_sys.h"
#include "sys.c"
// Fade in/out constants
#define fadefreq 4
// Fade in/out variables
unsigned char fade = 0;
unsigned char fadetimer = 0;

42
src/inputtest/fader.h Normal file
View File

@@ -0,0 +1,42 @@
/*============================================================================
Input Test - Fader
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef FADER_H
#define FADER_H
// Fade in/out constants
#define fadefreq 4
// Fade in/out variables
extern unsigned char fade;
extern unsigned char fadetimer;
// Initialise fadeout state
extern void start_fadeout();
// Initialise fadein state
extern void start_fadein();
// Fade out state
extern void fadeout();
// Fade in state
extern void fadein();
#endif

View File

@@ -1,29 +1,35 @@
/*============================================================================
Input Test - Input test state handlers
Input Test - Input test state handlers
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-13
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-13
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 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.
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 <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
#include "fader.c"
#include "menu.c"
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "../shared/ps2.h"
#include "../shared/sprite.h"
#include "fader.h"
#include "menu.h"
#include "sprite_images.h"
#include "inputtester_app.h"
#include "inputtester_sys.h"
#include "inputtester_ui.h"
#include "inputtester_pings.h"
// Input tester variables
unsigned char joystick_last[12];
@@ -42,9 +48,11 @@ unsigned char mse_button2_last = 255;
signed char mse_x_last = 1;
signed char mse_y_last = 1;
signed char mse_w_last = 1;
unsigned char mse_x_acc;
unsigned char mse_y_acc;
unsigned char mse_w_acc;
signed short mse_x_acc;
signed short mse_y_acc;
signed short mse_w_acc;
#define MOUSE_POINTER_SPRITE 9
// Mode switcher variables
char modeswitchtimer_select = 0;
@@ -261,6 +269,13 @@ void start_inputtester_advanced()
// Draw page
page_inputtester_advanced();
// Setup mouse pointer
enable_sprite(MOUSE_POINTER_SPRITE, sprite_palette_pointer, sprite_size_pointer, 0);
spr_index[MOUSE_POINTER_SPRITE] = sprite_index_pointer_first;
spr_on[MOUSE_POINTER_SPRITE] = 0;
mse_x_acc = 336;
mse_y_acc = 256;
// Reset last states for inputs
reset_inputstates();
}
@@ -316,12 +331,22 @@ void handle_codes()
{
pushhistory(5);
}
if (!input_b && input_b_last)
{
pushhistory(6);
}
// Check for SNEK code
if (history[0] == 1 && history[1] == 1 && history[2] == 2 && history[3] == 2 && history[4] == 3 && history[5] == 4 && history[6] == 5)
{
nextstate = STATE_START_ATTRACT;
pushhistory(0);
start_fadeout();
state = STATE_START_ATTRACT;
return;
}
// Check for Zorblax code
if (history[0] == 1 && history[1] == 1 && history[2] == 2 && history[3] == 2 && history[4] == 3 && history[5] == 4 && history[6] == 6)
{
pushhistory(0);
state = STATE_START_ZORBLAXX;
return;
}
}
@@ -329,6 +354,15 @@ void handle_codes()
// Menu opening handler
bool modeswitcher()
{
// Check system menu trigger
if (system_menu)
{
system_menu = 0;
modeswitchtimer_select = 0;
start_menu();
return 1;
}
// Open menu if select is held
if (input_select)
{
@@ -351,7 +385,7 @@ bool modeswitcher()
void inputtester_digital()
{
// // Handle PS/2 inputs whenever possible to improve latency
// Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Handle secret code detection (joypad 1 directions)
@@ -493,14 +527,16 @@ void inputtester_advanced()
// Handle test mode switch
if (modeswitcher())
{
clear_sprites();
update_sprites();
return;
}
// Draw joystick inputs (only update each byte if value has changed)
for (char inputindex = 0; inputindex < 6; inputindex++)
{
char m = 0b00000001;
char x = 6;
char mask = 0b00000001;
char cx = 6;
char y = 6 + inputindex;
char inputoffset = (inputindex * 4);
char lastoffset = (inputindex * 2);
@@ -511,18 +547,18 @@ void inputtester_advanced()
char joy = joystick[index];
if (joy != joystick_last[lastindex])
{
m = 0b00000001;
mask = 0b00000001;
char bytes = (b == 0 ? 8 : 4);
for (char i = 0; i < bytes; i++)
{
x++;
write_char((joy & m) ? asc_1 : asc_0, 0xFF, x, y);
m <<= 1;
cx++;
write_char((joy & mask) ? asc_1 : asc_0, 0xFF, cx, y);
mask <<= 1;
}
}
else
{
x += 8;
cx += 8;
}
joystick_last[lastindex] = joy;
}
@@ -595,12 +631,37 @@ void inputtester_advanced()
if (mse_changed)
{
// Mouse position accumulator
mse_x_acc += mse_x;
mse_y_acc += mse_y;
mse_y_acc -= mse_y;
mse_w_acc += mse_w;
write_stringf("%3d", 0xFF, 8, 23, mse_x_acc);
write_stringf("%3d", 0xFF, 12, 23, mse_y_acc);
// Enforce mouse pointer limit
if (mse_x_acc < 32)
{
mse_x_acc = 32;
}
else if (mse_x_acc >= 671)
{
mse_x_acc = 671;
}
if (mse_y_acc < 32)
{
mse_y_acc = 32;
}
else if (mse_y_acc >= 511)
{
mse_y_acc = 511;
}
unsigned short mx = (mse_x_acc / 2);
unsigned short my = (mse_y_acc / 2);
if (mse_x != 0 || mse_y != 0)
{
spr_on[MOUSE_POINTER_SPRITE] = 1;
set_sprite_position(MOUSE_POINTER_SPRITE, mx, my);
}
write_stringf_ushort("%3d", 0xFF, 8, 23, mx - 16);
write_stringf_ushort("%3d", 0xFF, 12, 23, my - 16);
write_stringf("%3d", 0xFF, 20, 23, mse_w_acc);
if (mse_button1_last != mse_button1)
@@ -613,8 +674,10 @@ void inputtester_advanced()
write_char((mse_button1 & m) ? asc_1 : asc_0, 0xFF, x, 23);
m <<= 1;
}
mse_button1_last = mse_button1;
input_mouse_left = CHECK_BIT(mse_button1, 0);
input_mouse_right = CHECK_BIT(mse_button1, 1);
}
mse_button1_last = mse_button1;
if (mse_button2_last != mse_button2)
{
char x = 31;
@@ -625,10 +688,23 @@ void inputtester_advanced()
write_char((mse_button2 & m) ? asc_1 : asc_0, 0xFF, x, 23);
m <<= 1;
}
mse_button2_last = mse_button2;
}
mse_button2_last = mse_button2;
if (input_mouse_left && !input_mouse_left_last)
{
add_ping(0, mx - 8, my - 8);
}
if (input_mouse_right && !input_mouse_right_last)
{
add_ping(1, mx - 8, my - 8);
}
mse_changed = 0;
}
handle_pings();
update_sprites();
}
}
@@ -780,14 +856,6 @@ void btntest_test()
}
}
unsigned short abs(signed short value)
{
if (value < 0)
{
value = value * -1;
}
return value;
}
// Button test - results view
void btntest_results()
{

View File

@@ -0,0 +1,78 @@
/*============================================================================
Input Test - Input test state handlers
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-13
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef INPUTTESTER_H
#define INPUTTESTER_H
// Mode switcher variables
extern char modeswitchtimer_select;
extern char modeswitchtimer_start;
#define PAD_COUNT 2
#define BUTTON_COUNT 12
#define color_button_active 0xFF
#define color_button_inactive 0b01010010
#define analog_size 18
#define analog_ratio 15 // 256 / 17;
#define timestamp_clock_index 32
#define timestamp_index_1 8
#define timestamp_index_2 16
#define timestamp_index_3 24
// Button test constants
#define btntest_mode_select 0
#define btntest_mode_ready 1
#define btntest_mode_test 2
#define btntest_mode_results 3
#define btntest_timer_start 60 // vblanks to wait before first prompt
#define btntest_timer_interval 90 // vblanks to wait between prompts
#define btntest_timer_visible 30 // vblanks to wait between prompts
#define btntest_counter_max 5 // Number of button presses required
#define btntest_max 255
#define btntest_highlight_start 2
#define btntest_highlight_end 35
// Initialise digital inputtester state and draw static elements
extern void start_inputtester_digital();
// Initialise analog inputtester state and draw static elements
extern void start_inputtester_analog();
// Initialise advanced inputtester state and draw static elements
extern void start_inputtester_advanced();
// Initialise button test state and draw static elements
extern void start_btntest();
// Digital input tester state
extern void inputtester_digital();
// Analog input tester state
extern void inputtester_analog();
// Advanced input tester state
extern void inputtester_advanced();
// Button test - mode handler
extern void btntest();
#endif

View File

@@ -0,0 +1,88 @@
/*============================================================================
Input Test - Mouse ping animations
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-12-22
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "sprite_images.h"
#include "inputtester_pings.h"
#define const_ping_max 8
unsigned char ping_max = const_ping_max;
unsigned char ping_sprite_first = 0;
unsigned char ping_timer[const_ping_max];
unsigned char ping_frame[const_ping_max];
unsigned char ping_type[const_ping_max];
const unsigned char ping_lifespan = 2;
#define ping_frame_count 7
#define ping_type_count 2
void setup_pings()
{
for (int e = ping_sprite_first; e < ping_sprite_first + ping_max; e++)
{
enable_sprite(e, sprite_palette_pings, sprite_size_pings, false);
spr_on[e] = false;
}
}
void add_ping(unsigned type, unsigned short x, unsigned short y)
{
for (unsigned char e = 0; e < ping_max; e++)
{
if (ping_timer[e] == 0)
{
ping_timer[e] = ping_lifespan;
ping_frame[e] = 0;
type = 0;
// ping_type[e] = type;
unsigned char sprite = ping_sprite_first + e;
enable_sprite(sprite, sprite_palette_pings, sprite_size_pings, 0);
spr_index[sprite] = sprite_index_pings_first + (type * ping_frame_count);
set_sprite_position(sprite, x, y);
return;
}
}
}
void handle_pings()
{
for (unsigned char t = 0; t < ping_max; t++)
{
if (ping_timer[t] > 0)
{
ping_timer[t]--;
if (ping_timer[t] == 0)
{
unsigned char sprite = ping_sprite_first + t;
spr_index[sprite]++;
ping_frame[t]++;
if (ping_frame[t] == ping_frame_count)
{
spr_on[sprite] = false;
}
else
{
ping_timer[t] = ping_lifespan;
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
/*============================================================================
Input Test - Mouse ping animations
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-12-22
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef INPUTTESTER_PINGS_H
#define INPUTTESTER_PINGS_H
extern unsigned char ping_max;
extern unsigned char ping_sprite_first;
extern unsigned char ping_timer[];
extern unsigned char ping_frame[];
extern unsigned char ping_type[];
extern const unsigned char ping_lifespan;
extern void setup_pings();
extern void add_ping(unsigned type, unsigned short x, unsigned short y);
extern void handle_pings();
#endif

View File

@@ -19,37 +19,9 @@
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
#include "ps2.c"
// Application states
#define STATE_START_INPUTTESTER 1
#define STATE_INPUTTESTER 2
#define STATE_START_INPUTTESTERADVANCED 3
#define STATE_INPUTTESTERADVANCED 4
#define STATE_START_INPUTTESTERANALOG 5
#define STATE_INPUTTESTERANALOG 6
#define STATE_START_BTNTEST 7
#define STATE_BTNTEST 8
#define STATE_START_MENU 9
#define STATE_MENU 10
#define STATE_FADEOUT 20
#define STATE_START_FADEIN 21
#define STATE_FADEIN 22
#define STATE_START_ATTRACT 30
#define STATE_ATTRACT 31
#define STATE_START_GAME_SNEK 40
#define STATE_GAME_SNEK 41
#define GET_TIMER ((unsigned short)timer[1] << 8) | (unsigned char)timer[0]
#include "../shared/sys.h"
#include "../shared/ps2.h"
#include "inputtester_sys.h"
// DPAD tracker
bool input_left = 0;
@@ -69,6 +41,17 @@ bool input_a_last = 0;
bool input_b;
bool input_b_last = 0;
// Mouse tracker
bool input_mouse_left;
bool input_mouse_left_last;
bool input_mouse_right;
bool input_mouse_right_last;
// Input tester application state
char state = 0;
char defaultstate = STATE_START_INPUTTESTER;
char nextstate = 0;
// Track joypad 1 directions and start for menu control
void basic_input()
{
@@ -80,12 +63,15 @@ void basic_input()
input_select_last = input_select;
input_a_last = input_a;
input_b_last = input_b;
input_up = CHECK_BIT(joystick[0], 3) || kbd_down[KEY_UP];
input_down = CHECK_BIT(joystick[0], 2) || kbd_down[KEY_DOWN];
input_left = CHECK_BIT(joystick[0], 1) || kbd_down[KEY_LEFT];
input_mouse_left_last = input_mouse_left;
input_mouse_right_last = input_mouse_right;
input_right = CHECK_BIT(joystick[0], 0) || kbd_down[KEY_RIGHT];
input_start = CHECK_BIT(joystick[1], 3) || kbd_down[KEY_1];
input_select = CHECK_BIT(joystick[1], 2) || kbd_down[KEY_ESC];
input_left = CHECK_BIT(joystick[0], 1) || kbd_down[KEY_LEFT];
input_down = CHECK_BIT(joystick[0], 2) || kbd_down[KEY_DOWN];
input_up = CHECK_BIT(joystick[0], 3) || kbd_down[KEY_UP];
input_a = CHECK_BIT(joystick[0], 4) || kbd_down[KEY_ENTER];
input_b = CHECK_BIT(joystick[0], 5) || kbd_down[KEY_SPACE];
input_start = CHECK_BIT(joystick[1], 3) || kbd_down[KEY_1]|| mse_button1;
input_select = CHECK_BIT(joystick[1], 2) || kbd_down[KEY_ESC] || mse_button2;
}

View File

@@ -0,0 +1,89 @@
/*============================================================================
Input Test - Custom system functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef INPUTTESTER_SYS_H
#define INPUTTESTER_SYS_H
// Application states
#define STATE_START_INPUTTESTER 1
#define STATE_INPUTTESTER 2
#define STATE_START_INPUTTESTERADVANCED 3
#define STATE_INPUTTESTERADVANCED 4
#define STATE_START_INPUTTESTERANALOG 5
#define STATE_INPUTTESTERANALOG 6
#define STATE_START_BTNTEST 7
#define STATE_BTNTEST 8
#define STATE_START_MENU 9
#define STATE_MENU 10
#define STATE_FADEOUT 20
#define STATE_START_FADEIN 21
#define STATE_FADEIN 22
#define STATE_START_ATTRACT 30
#define STATE_ATTRACT 31
#define STATE_START_GAME_SNEK 40
#define STATE_GAME_SNEK 41
#define STATE_START_CREDITS 42
#define STATE_START_ZORBLAXX 43
#define GET_TIMER ((unsigned short)timer[1] << 8) | (unsigned char)timer[0]
// DPAD tracker
extern bool input_left;
extern bool input_left_last;
extern bool input_right;
extern bool input_right_last;
extern bool input_up;
extern bool input_up_last;
extern bool input_down;
extern bool input_down_last;
extern bool input_start;
extern bool input_start_last;
extern bool input_select;
extern bool input_select_last;
extern bool input_a;
extern bool input_a_last;
extern bool input_b;
extern bool input_b_last;
// Mouse tracker
extern bool input_mouse_left;
extern bool input_mouse_left_last;
extern bool input_mouse_right;
extern bool input_mouse_right_last;
// Input tester application state
extern char state;
extern char defaultstate;
extern char nextstate;
// Track joypad 1 directions and start for menu control
extern void basic_input();
#endif

View File

@@ -18,10 +18,10 @@
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include <stdbool.h>
#define color_pad_outline 0xFE
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "inputtester_ui.h"
void page_frame(bool showMenuButton, bool showContinueButton)
{
@@ -93,8 +93,6 @@ void draw_pad(char xo, char yo)
write_char(char_corner_round_tr, color_pad_outline, xo + 25, yo);
}
#define color_analog_grid 0x23
// Draw game pad outline
void draw_analog(char xo, char yo, char xs, char ys)
{

View File

@@ -0,0 +1,35 @@
/*============================================================================
Input Test - Custom UI functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef INPUTTESTER_UI_H
#define INPUTTESTER_UI_H
#define color_pad_outline 0xFE
#define color_analog_grid 0x23
extern void page_frame(bool showMenuButton, bool showContinueButton);
// Draw game pad outline
extern void draw_pad(char xo, char yo);
// Draw game pad outline
extern void draw_analog(char xo, char yo, char xs, char ys);
#endif

120
src/inputtest/loader.c Normal file
View File

@@ -0,0 +1,120 @@
/*============================================================================
Aznable OS - System loader
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2022-01-07
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "../shared/sound.h"
#include "../shared/sprite.h"
#include "../shared/starfield.h"
#include "sound_samples.h"
const char *system_title = "AZNABLE";
// Loader (aesthetic pointlessness)
void intro_text(const char *text, unsigned char start_x, unsigned char start_y, unsigned char space_x, unsigned char speed, unsigned char flash_speed)
{
unsigned char text_timer = 0;
unsigned char text_length = 1;
unsigned char text_flash = 0;
unsigned char text_flash_timer = 0;
unsigned char text_char_count = strlen(text);
// Speed things up in debug mode
if (CHECK_BIT(input0, 0))
{
speed = 1;
flash_speed = 1;
}
while (1)
{
vblank = CHECK_BIT(input0, INPUT_VBLANK);
// Aznable title intro
if (VBLANK_RISING)
{
unsigned char xpos = start_x + ((text_length - 1) * space_x);
text_timer++;
if (text_timer == speed)
{
write_char(text[text_length - 1], 0xFF, xpos, start_y);
text_length++;
if (text_length > text_char_count)
{
break;
}
text_timer = 0;
text_flash_timer = 0;
}
else
{
text_flash_timer++;
if (text_flash_timer == flash_speed)
{
text_flash++;
if (text_flash == 2)
{
text_flash = 0;
}
if (text_flash == 1)
{
write_char(0, 0, xpos, start_y);
}
else
{
write_char(text[text_length - 1], 0xFF, xpos, start_y);
}
text_flash_timer = 0;
}
}
}
vblank_last = vblank;
}
}
void loader(const char *title)
{
// Set charmap area
chram_size = chram_cols * chram_rows;
// Clear charmap
clear_bgcolor(0);
clear_chars(0);
// Reset sprites
clear_sprites();
update_sprites();
// Reset starfields
disable_starfield();
// OS Intro
write_char('>', 0xFF, 0, 1);
intro_text(system_title, 2, 1, 2, 8, 1);
write_char(' ', 0xFF, 0, 1);
write_char('>', 0xFF, 0, 3);
intro_text("LOAD ", 2, 3, 1, 2, 1);
intro_text(title, 7, 3, 1, 2, 1);
write_char(' ', 0xFF, 0, 3);
write_char('>', 0xFF, 0, 5);
intro_text("...", 2, 5, 1, 8, 1);
// Clear characters
clear_char_area(0, 1, 1, 40, 3);
}

27
src/inputtest/loader.h Normal file
View File

@@ -0,0 +1,27 @@
/*============================================================================
Aznable OS - System loader
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2022-01-07
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef LOADER_H
#define LOADER_H
// System intro text
extern void loader(const char *title);
#endif

View File

@@ -1,5 +1,5 @@
/*============================================================================
Aznable OS - Popup menu functions
Aznable OS - Popup menu functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
@@ -18,42 +18,23 @@
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
// Menu constants
#define menu_tx 12
#define menu_bx 28
#define menu_my 15
#define menu_openholdtime 60
#define menu_count 4
#define menu_panel_outline_high 0xFF
#define menu_panel_outline_mid 0b00110110
#define menu_panel_outline_low 0b00100100
#define menu_panel_back 0x00
#define menu_outline_high 0b10111111
#define menu_outline_mid 0b10110110
#define menu_outline_low 0b01100100
#define menu_text 0b10110110
#define menu_back 0x00
#define menu_sel_outline_high 0b01011111
#define menu_sel_outline_mid 0b00010110
#define menu_sel_outline_low 0b00010100
#define menu_sel_text 0xFF
#define menu_sel_back 0b00001001
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "../shared/ps2.h"
#include "menu.h"
#include "inputtester_sys.h"
// Menu variables
char menu_timer = 0;
char menu_index;
bool menu_dirty = 0;
bool menu_ready = 0;
unsigned char menu_timer = 0;
unsigned char menu_index;
unsigned char menu_dirty = 0;
unsigned char menu_ready = 0;
char *menu_string[] = {
"Digital",
"Analog",
"Advanced",
"Button test"};
"Button test",
"Credits"};
// Initialise menu state
void start_menu()
@@ -66,9 +47,9 @@ void start_menu()
// Menu state
void menu()
{
// // Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// // Handle PS/2 inputs whenever possible to improve latency
handle_ps2();
// Check inputs at end of each scanline. Is this too much?!
if (HBLANK_RISING)
{
@@ -93,6 +74,8 @@ void menu()
}
if ((!input_start && input_start_last) || (!input_a && input_a_last) || (!input_b && input_b_last))
{
// Clear menu flag to avoid double trigger
system_menu = 0;
switch (menu_index)
{
case 0:
@@ -107,6 +90,9 @@ void menu()
case 3:
state = STATE_START_BTNTEST;
break;
case 4:
state = STATE_START_CREDITS;
break;
}
}
}
@@ -114,7 +100,7 @@ void menu()
// As soon as vsync is detected start drawing screen updates
if (VBLANK_RISING)
{
char maxsize = (menu_count * 3) + 1;
char maxsize = (menu_count * 3) + 1 + (menu_count % 2);
if (menu_timer < maxsize)
{
@@ -125,7 +111,7 @@ void menu()
if (oy1 > 1)
{
fill(menu_tx + 1, my - (oy1 - 1), menu_bx - 1, my + (oy2 - 1), 0, 0);
fill_bgcolor(menu_tx + 1, my - (oy1 - 1), menu_bx - 1, my + (oy2 - 1), menu_panel_back);
fill_bgcol(menu_tx + 1, my - (oy1 - 1), menu_bx - 1, my + (oy2 - 1), menu_panel_back);
}
menu_timer++;
if (menu_timer == maxsize)
@@ -137,20 +123,20 @@ void menu()
{
if (menu_dirty)
{
char ty = menu_my - ((menu_count * 3) / 2) + 1;
char ty = menu_my - ((menu_count * 3) / 2);
for (char m = 0; m < menu_count; m++)
{
if (menu_index == m)
{
panel_shaded(menu_tx + 1, ty, menu_bx - 1, ty + 2, menu_sel_outline_high, menu_sel_outline_mid, menu_sel_outline_low);
write_string(menu_string[m], menu_sel_text, menu_tx + 2, ty + 1);
//fill_bgcolor(menu_tx + 1, ty, menu_bx - 1, ty + 2, menu_sel_back);
// fill_bgcol(menu_tx + 1, ty, menu_bx - 1, ty + 2, menu_sel_back);
}
else
{
panel_shaded(menu_tx + 1, ty, menu_bx - 1, ty + 2, menu_outline_high, menu_outline_mid, menu_outline_low);
write_string(menu_string[m], menu_text, menu_tx + 2, ty + 1);
//fill_bgcolor(menu_tx + 1, ty, menu_bx - 1, ty + 2, menu_back);
// fill_bgcol(menu_tx + 1, ty, menu_bx - 1, ty + 2, menu_back);
}
ty += 3;
}

62
src/inputtest/menu.h Normal file
View File

@@ -0,0 +1,62 @@
/*============================================================================
Aznable OS - Popup menu functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-13
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef MENU_H
#define MENU_H
// Menu constants
#define menu_tx 12
#define menu_bx 28
#define menu_my 15
#define menu_openholdtime 60
#define menu_count 5
#define menu_panel_outline_high 0xFF
#define menu_panel_outline_mid 0b00110110
#define menu_panel_outline_low 0b00100100
#define menu_panel_back 0x00
#define menu_outline_high 0b10111111
#define menu_outline_mid 0b10110110
#define menu_outline_low 0b01100100
#define menu_text 0b10110110
#define menu_back 0x00
#define menu_sel_outline_high 0b01011111
#define menu_sel_outline_mid 0b00010110
#define menu_sel_outline_low 0b00010100
#define menu_sel_text 0xFF
#define menu_sel_back 0b00001001
// Menu variables
extern unsigned char menu_timer;
extern unsigned char menu_index;
extern unsigned char menu_dirty;
extern unsigned char menu_ready;
extern char *menu_string[];
// Initialise menu state
extern void start_menu();
// Menu state
extern void menu();
#endif

View File

@@ -0,0 +1,5 @@
#ifndef MUSIC_TRACKS_C
#define MUSIC_TRACKS_C
#include "music_tracks.h"
unsigned long music_track_address[] = {0u,32864u};
#endif

View File

@@ -0,0 +1,7 @@
#ifndef MUSIC_TRACKS_H
#define MUSIC_TRACKS_H
#define const_music_track_max 32
extern unsigned long music_track_address[const_music_track_max];
#define const_music_maintheme 0
#define const_music_gameover 1
#endif

View File

@@ -1,9 +1,9 @@
/*============================================================================
MiSTer test harness OS - Main application
Aznable OS - Input Tester main application
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
Version: 1.1
Date: 2022-01-07
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
@@ -18,23 +18,24 @@
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "sys.c"
#include "sys_custom.c"
#include "ps2.c"
#include "ui.c"
#include "ui_custom.c"
#include "menu.c"
#include "inputtester.c"
#include "snek.c"
#include "fader.c"
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "../shared/sprite.h"
#include "../shared/sound.h"
#include "../shared/tilemap.h"
#include "loader.h"
#include "sprite_images.h"
#include "sound_samples.h"
#include "inputtester_app.h"
#include "inputtester_sys.h"
#include "menu.h"
#include "zorblaxx_app.h"
#include "snek_app.h"
#include "fader.h"
#include "credits.h"
// Main entry and state machine
void main()
void app_main()
{
chram_size = chram_cols * chram_rows;
while (1)
@@ -42,7 +43,7 @@ void main()
hsync = input0 & 0x80;
vsync = input0 & 0x40;
hblank = input0 & 0x20;
vblank = input0 & 0x10;
vblank = CHECK_BIT(input0, INPUT_VBLANK);
switch (state)
{
case STATE_START_INPUTTESTER:
@@ -88,25 +89,38 @@ void main()
break;
case STATE_START_ATTRACT:
start_attract();
state = 0;
loader("SNEK.AZN");
start_snek_attract();
break;
case STATE_ATTRACT:
snek_attract();
break;
case STATE_START_CREDITS:
app_credits();
break;
case STATE_START_GAME_SNEK:
start_gameplay();
start_snek_gameplay();
break;
case STATE_GAME_SNEK:
snek_gameplay();
break;
case STATE_START_ZORBLAXX:
state = 0;
loader("ZORBLAXX.AZN");
app_zorblaxx();
break;
default:
// Start default state
//state = STATE_START_ZORBLAXX;
//state = STATE_START_CREDITS;
loader("INPUTTESTER.AZN");
start_inputtester_digital();
//start_inputtester_advanced();
//start_inputtester_analog();
//start_btntest();
// start_inputtester_advanced();
// start_inputtester_analog();
// start_btntest();
break;
}
@@ -116,3 +130,9 @@ void main()
vblank_last = vblank;
}
}
// Main entry
void main()
{
app_main();
}

View File

@@ -19,15 +19,13 @@
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "../shared/sys.h"
#include "../shared/ui.h"
#include "../shared/sprite.h"
#include "snek_app.h"
#include "inputtester_sys.h"
#include "fader.h"
#include "sys.c"
#include "fader.c"
// SNEK constants
#define movefreqinit 14
#define movefreqdecfreq 200
#define playerchar 83
// SNEK variables
unsigned char movefreqdectimer = 0;
unsigned char movefreq = 0;
@@ -44,7 +42,7 @@ unsigned int length = 0;
unsigned char attractstate = 0;
// Initialise attract state and draw static elements
void start_attract()
void start_snek_attract()
{
state = STATE_ATTRACT;
attractstate = 0;
@@ -56,7 +54,7 @@ void start_attract()
}
// Initialise attract state and draw static elements
void start_gameplay()
void start_snek_gameplay()
{
state = STATE_GAME_SNEK;
length = 0;
@@ -158,7 +156,7 @@ void snek_attract()
{
if (CHECK_BIT(joystick[1], 3)) // start to start
{
start_gameplay();
start_snek_gameplay();
return;
}
if (CHECK_BIT(joystick[1], 2)) // select to quit

56
src/inputtest/snek_app.h Normal file
View File

@@ -0,0 +1,56 @@
/*============================================================================
Input Test - Snek mini-game
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-07-12
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef SNEK_H
#define SNEK_H
// SNEK constants
#define movefreqinit 14
#define movefreqdecfreq 200
#define playerchar 83
// SNEK variables
extern unsigned char movefreqdectimer;
extern unsigned char movefreq;
extern unsigned char movetimer;
extern signed int x;
extern signed int y;
extern signed char xd;
extern signed char yd;
extern signed char nxd;
extern signed char nyd;
extern unsigned int length;
// Attract mode variables
extern unsigned char attractstate;
// Initialise attract state and draw static elements
extern void start_snek_attract();
// Initialise attract state and draw static elements
extern void start_snek_gameplay();
// SNEK - gameplay state
extern void snek_gameplay();
// SNEK - attract state
extern void snek_attract();
#endif

View File

@@ -0,0 +1,6 @@
#ifndef SOUND_SAMPLES_C
#define SOUND_SAMPLES_C
#include "sound_samples.h"
unsigned long sound_sample_address[] = {0u,4888u,5075u,5983u};
unsigned long sound_sample_length[] = {4888u,187u,908u,5558u};
#endif

View File

@@ -0,0 +1,10 @@
#ifndef SOUND_SAMPLES_H
#define SOUND_SAMPLES_H
#define const_sound_sample_max 32
extern unsigned long sound_sample_address[const_sound_sample_max];
extern unsigned long sound_sample_length[const_sound_sample_max];
#define const_sound_player_explode 0
#define const_sound_pickup_collect 1
#define const_sound_alarm 2
#define const_sound_newtype 3
#endif

View File

@@ -0,0 +1,59 @@
#ifndef SPRITE_IMAGES_H
#define SPRITE_IMAGES_H
#define sprite_index_title_first 0
#define sprite_index_title_count 4
#define sprite_index_title_last 3
#define sprite_palette_title 2
#define sprite_size_title 0
#define sprite_pixelsize_title 32
#define sprite_halfpixelsize_title 16
#define sprite_index_asteroids_first 0
#define sprite_index_asteroids_count 8
#define sprite_index_asteroids_last 7
#define sprite_palette_asteroids 0
#define sprite_size_asteroids 1
#define sprite_pixelsize_asteroids 16
#define sprite_halfpixelsize_asteroids 8
#define sprite_index_explosions_first 8
#define sprite_index_explosions_count 8
#define sprite_index_explosions_last 15
#define sprite_palette_explosions 1
#define sprite_size_explosions 1
#define sprite_pixelsize_explosions 16
#define sprite_halfpixelsize_explosions 8
#define sprite_index_pickups_first 16
#define sprite_index_pickups_count 8
#define sprite_index_pickups_last 23
#define sprite_palette_pickups 1
#define sprite_size_pickups 1
#define sprite_pixelsize_pickups 16
#define sprite_halfpixelsize_pickups 8
#define sprite_index_pings_first 24
#define sprite_index_pings_count 8
#define sprite_index_pings_last 31
#define sprite_palette_pings 2
#define sprite_size_pings 1
#define sprite_pixelsize_pings 16
#define sprite_halfpixelsize_pings 8
#define sprite_index_player_first 32
#define sprite_index_player_count 4
#define sprite_index_player_last 35
#define sprite_palette_player 1
#define sprite_size_player 1
#define sprite_pixelsize_player 16
#define sprite_halfpixelsize_player 8
#define sprite_index_pointer_first 36
#define sprite_index_pointer_count 1
#define sprite_index_pointer_last 36
#define sprite_palette_pointer 2
#define sprite_size_pointer 1
#define sprite_pixelsize_pointer 16
#define sprite_halfpixelsize_pointer 8
#define sprite_index_trails_first 0
#define sprite_index_trails_count 4
#define sprite_index_trails_last 3
#define sprite_palette_trails 1
#define sprite_size_trails 2
#define sprite_pixelsize_trails 8
#define sprite_halfpixelsize_trails 4
#endif

View File

@@ -0,0 +1,667 @@
/*============================================================================
Aznable OS - Zorblaxx demo application
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
/*
Sprite indexes:
0-9 - Trails
10 - Pickup
11 - Player
12-27 - Asteroids
28-31 - Explosions
*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "../shared/tilemap.h"
#include "../shared/ui.h"
#include "../shared/music.h"
#include "../shared/sound.h"
#include "../shared/starfield.h"
#include "sprite_images.h"
#include "sound_samples.h"
#include "music_tracks.h"
#include "zorblaxx_app.h"
#include "zorblaxx_player.h"
#include "zorblaxx_trails.h"
#include "zorblaxx_explosions.h"
#include "zorblaxx_pickups.h"
#include "zorblaxx_asteroids.h"
// Area and units
const unsigned char x_divisor = 16;
const unsigned char y_divisor = 16;
unsigned short x_min = 2;
unsigned short x_max = 336;
unsigned short x_h_min;
unsigned short x_h_max;
unsigned char scroll_speed;
// Game defaults
unsigned short player_spawn_x = ((320 / 2) - 8) + 32;
unsigned short player_spawn_y = 200;
// Game states
typedef enum
{
game_start,
enter_field,
in_field,
field_ending,
field_complete,
in_warp,
approaching_field,
game_over,
game_over_waitforstats,
game_over_stats,
game_over_waitforscoreentry
} game_state_enum;
game_state_enum game_state = 0;
unsigned short game_state_timer = 0;
// Level progression
unsigned char level_number = 0;
unsigned char level_time = 0;
unsigned char level_time_timer = 0;
unsigned char level_playercontrol = 0;
unsigned short level_progress = 0;
unsigned char level_progress_timer = 0;
unsigned short level_progress_max;
unsigned short level_progress_base = 20000;
const unsigned short level_progress_per_level = 3000;
unsigned short game_state_warp_timeout_first = 120;
unsigned short game_state_warp_timeout = 240;
unsigned short game_state_danger_timeout = 120;
unsigned short game_state_gameover_timeout = 180;
const unsigned char asteroids_difficulty_base = 3;
const unsigned char asteroids_difficulty_multiplier = 2;
unsigned char player_lives_default = 3;
unsigned char pickup_spawn_timer = 0;
unsigned char pickup_spawn_timer_min = 120;
unsigned long high_score = 5000;
unsigned char bonus_score_multiplier = 10;
unsigned long player_score = 0;
unsigned long player_score_last;
unsigned long time_bonuses_collected;
unsigned long pickup_bonuses_collected;
unsigned char high_score_passed = 0;
unsigned char player_score_timer = 0;
unsigned char player_score_timer_frequency = 100;
unsigned char button_a;
unsigned char button_a_last;
unsigned char pleaseStop; // Set to 1 to fall back to OS
void setup_variables()
{
pleaseStop = 0;
x_h_min = (unsigned short)(x_min * x_divisor);
x_h_max = (unsigned short)(x_max * x_divisor);
unsigned char debug = CHECK_BIT(input0, 0);
if (debug)
{
game_state_warp_timeout_first /= 10;
game_state_warp_timeout /= 10;
game_state_danger_timeout /= 10;
game_state_gameover_timeout /= 10;
player_lives_default = 1;
level_progress_base = 2000;
}
}
const char *scroller_text = "CODE AND GFX BY JIMMYSTONES ... MUSIC BY DARRIN CARDANI ... ";
unsigned char scroller_pos = 0;
unsigned short scroller_entry_pos = (14 * 32) + 21;
void update_scroller()
{
tilemap_offset_x += 2;
if (tilemap_offset_x >= 16)
{
tilemap_offset_x -= 16;
scroll_tilemap_left();
tilemapram[scroller_entry_pos] = scroller_text[scroller_pos] - 45;
scroller_pos++;
if (scroller_pos == strlen(scroller_text))
{
scroller_pos = 0;
}
}
}
void intro_loop()
{
clear_bgcolor(0);
// Start intro music loop
play_music_if(const_music_maintheme, 1);
// Setup starfield layer speeds
enable_starfield();
set_starfield_speed_x(0);
set_starfield_speed_y(-0.5f);
// Setup title sprites
unsigned char title_sprite = 16;
unsigned short title_x = ((320 / 2) + 32) - 64;
signed short title_y = -32 * y_divisor;
signed short title_target_y = 100 * y_divisor;
unsigned char si = 0;
for (unsigned char y = 0; y < 1; y++)
{
for (unsigned char x = 0; x < 4; x++)
{
enable_sprite(title_sprite, sprite_palette_title, sprite_size_title, 0);
spr_index[title_sprite] = sprite_index_title_first + si;
set_sprite_position(title_sprite, title_x + (x * 32), -32);
si++;
title_sprite++;
}
}
unsigned char show_instruction = 0;
unsigned char title_ready = 0;
while (1)
{
vblank = CHECK_BIT(input0, INPUT_VBLANK);
if (VBLANK_RISING)
{
button_a_last = button_a;
button_a = CHECK_BIT(joystick[0], 4);
// If button pressed, leave intro and start game
if (button_a && !button_a_last)
{
return;
}
update_scroller();
update_tilemap_offset();
update_sprites();
// Press select to quit
if (CHECK_BIT(joystick[1], 2))
{
pleaseStop = 1;
return;
}
}
if (VBLANK_FALLING)
{
// Move title into position
if (title_y < title_target_y)
{
signed short diff = (title_target_y - title_y) / 6;
if (diff > 64)
{
diff = 64;
}
else if (diff == 0)
{
diff = 2;
}
title_y += diff;
title_sprite = 16;
for (unsigned char y = 0; y < 2; y++)
{
unsigned short sy = (title_y / y_divisor) + (y * 16);
for (unsigned char x = 0; x < 8; x++)
{
spr_y_h[title_sprite] = sy >> 8;
spr_y_l[title_sprite] = (unsigned char)sy;
title_sprite++;
}
}
}
else
{
title_ready = 1;
}
// Move player into position
move_player_to_target();
if (show_instruction == 0 && player_ready == 1 && title_ready == 1)
{
write_string("Press A to start", 0xFF, 12, 17);
show_instruction = 1;
}
// Trail
player_trail_timer--;
if (player_trail_timer <= 0)
{
player_trail_timer = player_trail_frequency - ((player_speed * 10) / 50);
if (player_trail_timer <= 0)
{
player_trail_timer = 1;
}
add_player_trail();
}
handle_trails();
}
vblank_last = vblank;
}
}
// Starfield variables
unsigned char scroll_speed_last = 0;
unsigned char sf_speed1 = 4;
void game_loop()
{
game_state = game_start;
while (1)
{
vblank = CHECK_BIT(input0, INPUT_VBLANK);
if (VBLANK_RISING)
{
// Detect player collision
if (spritecollisionram[player_sprite])
{
if (spritecollisionram[pickup_sprite_first])
{
// Player collects pickup
if (pickup_state[0] == 1)
{
enable_sprite(pickup_sprite_first, sprite_palette_pickups, sprite_size_pickups, 0);
player_score += pickup_value[0];
pickup_bonuses_collected += pickup_value[0];
pickup_state[0] = 2;
pickup_timer[0] = 40;
spr_index[pickup_sprite_first] += pickup_type_count;
play_sound(const_sound_pickup_collect);
}
}
else
{
for (unsigned char a = 0; a < asteroids_max; a++)
{
if (spritecollisionram[asteroids_sprite_first + a])
{
player_hit = true;
break;
}
}
}
}
for (unsigned char sprite = 0; sprite < sprite_max; sprite++)
{
spritecollisionram[sprite] = 0;
}
// Update sprite registers
update_sprites();
// Update starfield
scroll_speed = player_speed;
if (scroll_speed != scroll_speed_last)
{
scroll_speed_last = scroll_speed;
set_starfield_speed_y(scroll_speed * -0.02f);
}
// Track player button press
button_a_last = button_a;
button_a = CHECK_BIT(joystick[0], 4);
// Press Select to quit
if (CHECK_BIT(joystick[1], 2))
{
pleaseStop = 1;
return;
}
}
if (VBLANK_FALLING)
{
if (player_lives > 0)
{
handle_player(level_playercontrol);
}
handle_trails();
handle_explosions();
handle_asteroids(game_state == in_field);
handle_pickups();
if (game_state == in_field || game_state == field_ending)
{
level_time_timer++;
if (level_time_timer >= 60)
{
level_time++;
level_time_timer = 0;
}
if (player_lives_changed)
{
write_stringf("%2d", 0xFF, 38, 1, player_lives);
player_lives_changed = false;
if (player_lives == 0)
{
game_state = game_over;
}
}
}
// Game state machine
switch (game_state)
{
case game_start:
// Reset progress
level_number = 0;
level_progress = 0;
level_playercontrol = 0;
// Reset player
setup_player(player_spawn_x, 260, player_lives_default);
player_speed = player_speed_warp; // Preset player to warp speed!
// Reset scores and stats
player_score = 0;
player_score_last = 999;
player_score_timer = 0;
high_score_passed = 0;
asteroids_evaded = 0;
// Setup asteroids
setup_asteroids();
// Setup explosions
setup_explosions();
// Setup pickups
setup_pickups();
pickup_spawn_timer = pickup_spawn_timer_min;
// Draw score titles
write_string("1UP", 0b00111111, 2, 0);
write_string("HIGH SCORE", 0b00111111, 15, 0);
write_string("SHIPS", 0b00111111, 35, 0);
write_stringf("%2d", 0xFF, 38, 1, player_lives);
// Draw instructions for first warp
write_string("Avoid the asteroids!", 0b00111111, 10, 11);
write_string("Use A to boost for time bonus", 0b00111000, 5, 14);
write_string("Collect gems for extra points", 0b00011111, 5, 17);
game_state = in_warp;
game_state_timer = game_state_warp_timeout_first;
break;
case enter_field: // Player is entering a new field
game_state = in_field;
level_progress = 0;
level_progress_timer = 0;
level_number++;
level_time = 0;
level_time_timer = 0;
level_playercontrol = 1;
unsigned short per_level = level_number < 13 ? (level_number * level_progress_per_level) : 13 * level_progress_per_level;
level_progress_max = level_progress_base + per_level;
// Start main music loop
play_music_if(const_music_maintheme, 1);
// Update asteroid difficulty
asteroids_difficulty = asteroids_difficulty_base + (level_number * asteroids_difficulty_multiplier);
asteroids_difficulty_speedspread = 2 + (asteroids_difficulty / 4);
asteroids_active_max = 5 + asteroids_difficulty;
if (asteroids_active_max > asteroids_max)
{
asteroids_active_max = asteroids_max;
}
// Write 0% progress indicator
write_stringf("%3d%%", 0xFF, 18, 29, 0);
break;
case in_field:
// Level progress
level_progress += player_speed;
level_progress_timer++;
if (level_progress_timer > 10)
{
unsigned char progress = level_progress / (level_progress_max / 100);
write_stringf("%3d%%", 0xFF, 18, 29, progress);
level_progress_timer = 0;
}
if (level_progress >= level_progress_max)
{
write_string("100%", 0xFF, 18, 29);
game_state = field_ending;
}
// Generate pickups
pickup_spawn_timer--;
if (pickup_spawn_timer == 0)
{
pickup_spawn_timer = pickup_spawn_timer_min;
spawn_pickup();
}
// Player score
player_score_timer += player_speed;
if (player_score_timer >= player_score_timer_frequency)
{
player_score_timer -= player_score_timer_frequency;
player_score++;
}
break;
case field_ending:
// Level ended - wait for all asteroids to clear
// Keep scoring until asteroids are clear
player_score_timer += player_speed;
if (player_score_timer >= player_score_timer_frequency)
{
player_score_timer -= player_score_timer_frequency;
player_score++;
}
if (asteroids_active == 0)
{
game_state = field_complete;
game_state_timer = 0;
game_state_timer = game_state_warp_timeout;
// Start score music loop
level_playercontrol = 0;
set_player_target(player_spawn_x * x_divisor, player_spawn_y * y_divisor, 6, 24);
write_stringf_ushort("-- FIELD %d COMPLETED --", 0xFF, 9, 11, level_number);
unsigned char par_speed = ((player_speed_max - player_speed_min) / 2);
unsigned short par_time = level_progress_max / 60 / par_speed;
signed short bonus = (par_time - level_time) * bonus_score_multiplier;
time_bonuses_collected += bonus;
if (bonus < 0)
{
if ((-bonus) > player_score)
{
bonus = -player_score;
}
}
player_score += bonus;
write_stringf_ushort("Time: %6d", 0xFF, 14, 13, level_time);
write_stringf_ushort("Par: %6d", 0xFF, 15, 14, par_time);
if (bonus > 0)
{
write_stringf_short("Bonus: %6d", 0b00011000, 13, 16, bonus);
}
else
{
write_string("No bonus :(", 0b01011011, 14, 16);
}
write_stringf_ulong("Score: %6d", 0xFF, 13, 18, player_score);
clear_char_area(0, 10, 29, 30, 29);
}
break;
case field_complete: // Display field completed screen while bringing ship up to speed
move_player_to_target();
if (player_speed < player_speed_warp)
{
player_speed++;
}
else
{
game_state = in_warp;
}
break;
case in_warp: // Do a bit of warp speed
move_player_to_target();
game_state_timer--;
if (game_state_timer == 0)
{
clear_char_area(0, 0, 2, 39, 20);
write_string("- Entering asteroid field -", 0xFF, 07, 16);
game_state = approaching_field;
game_state_timer = game_state_danger_timeout;
level_time = 0;
}
break;
case approaching_field: // Slow down again ready for start
move_player_to_target();
if (player_speed > player_speed_min)
{
player_speed--;
}
level_time_timer++;
if (level_time_timer >= 15)
{
play_sound(const_sound_alarm);
write_string("DANGER!", level_time ? 0b00000111 : 0b00111111, 16, 14);
level_time = !level_time;
level_time_timer = 0;
}
game_state_timer--;
if (game_state_timer == 0)
{
clear_char_area(0, 0, 14, 39, 16);
game_state = enter_field;
setup_asteroids();
}
break;
case game_over:
write_string("GAME OVER", 0b00000011, 16, 14);
stop_music();
game_state_timer = game_state_gameover_timeout;
game_state = game_over_waitforstats;
break;
case game_over_waitforstats:
game_state_timer--;
if (game_state_timer == 0)
{
play_music(const_music_gameover, 1);
clear_char_area(0, 0, 14, 39, 14);
// Write stats
write_stringf_ulong("Final Score: %6d", 0xFF, 10, 11, player_score);
write_stringf_ulong("Asteroids evaded: %6d", 0b00111111, 5, 14, asteroids_evaded);
write_stringf_ulong("Time bonuses: %6d", 0b00111000, 9, 16, time_bonuses_collected);
write_stringf_ulong("Pickup bonuses: %6d", 0b00011111, 7, 18, pickup_bonuses_collected);
write_string("Press A to continue", 0xFF, 10, 21);
game_state = game_over_waitforscoreentry;
}
break;
case game_over_waitforscoreentry:
if (button_a && !button_a_last)
{
return;
}
break;
}
// Only update scores if they have changed
if (player_score != player_score_last)
{
// Update high score
if (player_score > high_score)
{
high_score = player_score;
}
// Draw player score
write_stringf_ulong("%d", 0xFF, 0, 1, player_score);
// Draw highscore
write_stringf_ulong("%6d", 0xFF, 16, 1, high_score);
player_score_last = player_score;
}
}
vblank_last = vblank;
}
}
void app_zorblaxx()
{
setup_variables();
stop_music();
while (1)
{
clear_chars(0);
clear_sprites();
if (pleaseStop)
{
return;
}
setup_player(player_spawn_x, 256, player_lives_default);
set_player_target(player_spawn_x * x_divisor, player_spawn_y * y_divisor, 6, 24);
setup_trails();
intro_loop();
// Clear character map and title sprites
clear_tilemap();
clear_chars(0);
clear_sprites();
if (pleaseStop)
{
return;
}
game_loop();
}
}

View File

@@ -0,0 +1,50 @@
/*============================================================================
Aznable OS - Zorblaxx demo application
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef ZORBLAXX_APP_H
#define ZORBLAXX_APP_H
// Area and units
extern const unsigned char x_divisor;
extern const unsigned char y_divisor;
extern unsigned short x_min;
extern unsigned short x_max;
extern unsigned short x_h_min;
extern unsigned short x_h_max;
extern unsigned char scroll_speed;
// Game defaults
extern unsigned short player_spawn_x;
extern unsigned short player_spawn_y;
// Sprite indexes
#define trail_sprite_first 0
#define pickup_sprite_first 10
#define player_sprite 11
#define asteroids_sprite_first 12
#define explosion_sprite_first 29
// Method headers
extern void intro_loop();
extern void game_loop();
extern void app_zorblaxx();
#endif

View File

@@ -0,0 +1,123 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Asteroid routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "sprite_images.h"
#include "zorblaxx_app.h"
#include "zorblaxx_asteroids.h"
#define const_asteroids_max 16
unsigned char asteroids_max = const_asteroids_max;
unsigned short asteroids_x[const_asteroids_max];
unsigned short asteroids_y[const_asteroids_max];
signed char asteroids_xs[const_asteroids_max];
signed char asteroids_ys[const_asteroids_max];
unsigned char asteroids_timer[const_asteroids_max];
unsigned short asteroids_y_max;
unsigned char asteroid_spawn_y = 0;
unsigned char asteroids_active;
unsigned char asteroids_active_max;
unsigned char asteroids_difficulty;
unsigned char asteroids_difficulty_speedspread;
unsigned short asteroids_evaded = 0;
unsigned char get_asteroid_timer()
{
unsigned char min_wait = asteroids_difficulty < 30 ? 30 - asteroids_difficulty : 0;
unsigned char max_wait = asteroids_difficulty < 120 ? 120 - asteroids_difficulty : 0;
unsigned char random = rand_uchar(min_wait, max_wait);
return random;
}
void setup_asteroids()
{
asteroids_y_max = 272 * y_divisor;
for (unsigned char m = 0; m < asteroids_max; m++)
{
asteroids_x[m] = rand_ushort(32, 320) * x_divisor;
asteroids_y[m] = asteroid_spawn_y;
asteroids_xs[m] = rand_schar(-asteroids_difficulty_speedspread, asteroids_difficulty_speedspread);
asteroids_ys[m] = rand_uchar(4, 16 + asteroids_difficulty);
asteroids_timer[m] = get_asteroid_timer();
unsigned char sprite = asteroids_sprite_first + m;
spr_index[sprite] = sprite_index_asteroids_first + rand_uchar(0, sprite_index_asteroids_count - 1);
enable_sprite(sprite, sprite_palette_asteroids, sprite_size_asteroids, true);
spr_on[sprite] = false;
set_sprite_position(sprite, asteroids_x[m] / x_divisor, 0);
}
}
void handle_asteroids(unsigned char spawn_enabled)
{
asteroids_active = 0;
for (unsigned char m = 0; m < asteroids_max; m++)
{
unsigned char sprite = asteroids_sprite_first + m;
if (m < asteroids_active_max)
{
if (asteroids_timer[m] > 0)
{
if (spawn_enabled == 1)
{
asteroids_timer[m]--;
if (asteroids_timer[m] == 0)
{
spr_index[sprite] = rand_uchar(sprite_index_asteroids_first, sprite_index_asteroids_last);
spr_on[sprite] = 1;
}
}
}
else
{
asteroids_active++;
asteroids_x[m] += asteroids_xs[m];
if (asteroids_x[m] < x_h_min)
{
asteroids_x[m] = x_h_max;
}
else if (asteroids_x[m] > x_h_max)
{
asteroids_x[m] = x_h_min;
}
if (asteroids_y[m] >= asteroids_y_max)
{
spr_on[sprite] = 0;
asteroids_x[m] = rand_ushort(32, 320) * x_divisor;
asteroids_y[m] = asteroid_spawn_y * y_divisor;
set_sprite_position(sprite, asteroids_x[m] / x_divisor, asteroid_spawn_y);
asteroids_xs[m] = rand_schar(-asteroids_difficulty_speedspread, asteroids_difficulty_speedspread);
asteroids_ys[m] = rand_uchar(4, 16 + asteroids_difficulty);
asteroids_timer[m] = get_asteroid_timer();
asteroids_evaded++;
}
else
{
asteroids_y[m] += asteroids_ys[m] + scroll_speed;
set_sprite_position(sprite, asteroids_x[m] / x_divisor, asteroids_y[m] / y_divisor);
}
}
}
}
}

View File

@@ -0,0 +1,43 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Asteroid routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef ZORBLAXX_ASTEROIDS_H
#define ZORBLAXX_ASTEROIDS_H
extern unsigned char asteroids_max;
extern unsigned short asteroids_x[];
extern unsigned short asteroids_y[];
extern signed char asteroids_xs[];
extern signed char asteroids_ys[];
extern unsigned char asteroids_timer[];
extern unsigned short asteroids_y_max;
extern unsigned char asteroids_active_max;
extern unsigned char asteroids_active;
extern unsigned char asteroids_difficulty;
extern unsigned char asteroids_difficulty_speedspread;
extern unsigned short asteroids_evaded;
extern void setup_asteroids();
extern void handle_asteroids(unsigned char spawn_enabled);
#endif

View File

@@ -0,0 +1,93 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Explosion routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "sprite_images.h"
#include "zorblaxx_app.h"
#include "zorblaxx_player.h"
#include "zorblaxx_explosions.h"
// Explosions
#define const_explosion_max 3
unsigned char explosion_max = const_explosion_max;
unsigned char explosion_timer[const_explosion_max];
unsigned char explosion_frame[const_explosion_max];
unsigned char explosion_type[const_explosion_max];
const unsigned char explosion_lifespan = 4;
#define explosion_frame_count 4
#define explosion_type_count 2
void setup_explosions()
{
for (int e = explosion_sprite_first; e < explosion_sprite_first + explosion_max; e++)
{
enable_sprite(e, sprite_palette_explosions, sprite_size_explosions, 0);
spr_on[e] = false;
}
}
void add_explosion(unsigned type, unsigned char count)
{
for (unsigned char e = 0; e < explosion_max; e++)
{
if (explosion_timer[e] == 0)
{
explosion_timer[e] = rand_uchar(2, 7);
explosion_frame[e] = 0;
explosion_type[e] = type;
unsigned char sprite = explosion_sprite_first + e;
spr_on[sprite] = 1;
spr_index[sprite] = sprite_index_explosions_first + (type * explosion_frame_count);
set_sprite_position(sprite, (player_x / x_divisor) + rand_schar(-4, 8), (player_y / y_divisor) + rand_schar(-4, 8));
count--;
if (count == 0)
{
return;
}
}
}
}
void handle_explosions()
{
for (unsigned char t = 0; t < explosion_max; t++)
{
if (explosion_timer[t] > 0)
{
explosion_timer[t]--;
if (explosion_timer[t] == 0)
{
unsigned char sprite = explosion_sprite_first + t;
spr_index[sprite]++;
explosion_frame[t]++;
if (explosion_frame[t] == explosion_frame_count)
{
spr_on[sprite] = false;
}
else
{
explosion_timer[t] = explosion_lifespan;
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Explosion routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef ZORBLAXX_EXPLOSIONS_H
#define ZORBLAXX_EXPLOSIONS_H
// Explosions
extern unsigned char explosion_max;
extern unsigned char explosion_timer[];
extern unsigned char explosion_frame[];
extern unsigned char explosion_type[];
extern const unsigned char explosion_lifespan;
extern void setup_explosions();
extern void add_explosion(unsigned type, unsigned char count);
extern void handle_explosions();
#endif

View File

@@ -0,0 +1,107 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Pickup routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "sprite_images.h"
#include "zorblaxx_app.h"
#include "zorblaxx_pickups.h"
#include "zorblaxx_asteroids.h"
#include "zorblaxx_player.h"
#define const_pickup_max 1
#define const_type_count 4
unsigned char pickup_max = const_pickup_max;
unsigned char pickup_type_count = const_type_count;
unsigned char pickup_spawn_y = 0;
unsigned char pickup_spawn_interval = 10;
unsigned short pickup_x[const_pickup_max];
unsigned short pickup_y[const_pickup_max];
signed char pickup_ys[const_pickup_max];
unsigned char pickup_state[const_pickup_max];
unsigned char pickup_value[const_pickup_max];
unsigned char pickup_timer[const_pickup_max];
unsigned short pickup_y_max;
unsigned char pickup_y_offset;
void spawn_pickup()
{
for (unsigned char t = 0; t < pickup_max; t++)
{
if (pickup_state[t] == 0)
{
unsigned char sprite = pickup_sprite_first + t;
unsigned char type = rand_uchar(0, const_type_count - 1);
pickup_x[t] = rand_ushort(48, 272) * x_divisor;
pickup_y[t] = pickup_spawn_y * y_divisor;
pickup_ys[t] = rand_uchar(0, type * 12);
pickup_state[t] = 1;
pickup_value[t] = 50 * (type + 1);
enable_sprite(sprite, sprite_palette_pickups, sprite_size_pickups, 1);
spr_index[sprite] = sprite_index_pickups_first + type;
set_sprite_position(sprite, pickup_x[t] / x_divisor, pickup_spawn_y);
return;
}
}
}
void setup_pickups()
{
pickup_y_max = 272 * y_divisor;
pickup_y_offset = (8 * y_divisor);
for (int t = pickup_sprite_first; t < pickup_sprite_first + pickup_max; t++)
{
enable_sprite(t, sprite_palette_pickups, sprite_size_pickups, false);
spr_on[t] = false;
}
}
void handle_pickups()
{
for (unsigned char t = 0; t < pickup_max; t++)
{
if (pickup_state[t] > 0)
{
unsigned char sprite = pickup_sprite_first + t;
pickup_y[t] += (pickup_ys[t] + scroll_speed);
if ((pickup_y[t] > pickup_y_max) > 0)
{
spr_on[sprite] = false;
pickup_state[t] = 0;
continue;
}
if (pickup_state[t] == 2)
{
pickup_timer[t]--;
if (pickup_timer[t] == 0)
{
spr_on[sprite] = false;
pickup_state[t] = 0;
pickup_timer[t] = pickup_spawn_interval;
continue;
}
}
set_sprite_position(sprite, pickup_x[t] / x_divisor, pickup_y[t] / y_divisor);
}
}
}

View File

@@ -0,0 +1,38 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Pickup routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef ZORBLAXX_PICKUPS_H
#define ZORBLAXX_PICKUPS_H
// Pickups
extern unsigned char pickup_max;
extern unsigned char pickup_type_count;
extern unsigned char pickup_state[];
extern unsigned char pickup_value[];
extern unsigned char pickup_timer[];
extern void spawn_pickup();
extern void setup_pickups();
extern void handle_pickups();
#endif

View File

@@ -0,0 +1,380 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Player routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "../shared/sound.h"
#include "sprite_images.h"
#include "sound_samples.h"
#include "zorblaxx_app.h"
#include "zorblaxx_player.h"
#include "zorblaxx_trails.h"
#include "zorblaxx_asteroids.h"
#include "zorblaxx_explosions.h"
// Player
const signed char player_max_speed = 20;
const unsigned char player_accel = 3;
const unsigned char player_trail_frequency = 10;
const unsigned char player_trail_speed = 3;
const unsigned char player_trail_lifespan = 5;
unsigned short player_x;
unsigned short player_y;
signed char player_xs = 0;
signed char player_ys = 0;
unsigned short player_x_min;
unsigned short player_x_max;
unsigned short player_y_min;
unsigned short player_y_max;
const unsigned char player_speed_min = 12;
const unsigned char player_speed_max = 32;
const unsigned char player_speed_warp = 64;
unsigned char player_speed;
signed char player_trail_timer = 1;
unsigned char player_lives;
unsigned char player_lives_changed;
unsigned char player_invincible_timer = 0;
unsigned char player_invincible_flash = 0;
const unsigned char player_invincible_timeout = 120;
unsigned char player_respawn_timer = 0;
const unsigned char player_respawn_timeout = 120;
unsigned char player_hit = 0;
unsigned char player_ready;
unsigned char player_ready_x;
unsigned char player_ready_y;
unsigned short player_x_target;
unsigned short player_y_target;
signed short player_x_diff;
signed short player_y_diff;
unsigned char player_target_divider = 6;
unsigned char player_target_maxspeed = 28;
void set_player_target(unsigned short x, unsigned short y, unsigned char divider, unsigned char maxspeed)
{
player_ready = 0;
player_ready_x = 0;
player_ready_y = 0;
player_x_target = x;
player_y_target = y;
player_target_divider = divider;
player_target_maxspeed = maxspeed;
}
void move_player_to_target()
{
if (player_y != player_y_target)
{
player_y_diff = (((signed short)player_y_target - (signed short)player_y)) / (signed char)player_target_divider;
if (player_y_diff == 0)
{
player_y = player_y_target;
}
else
{
if (player_y_diff > player_target_maxspeed)
{
player_y_diff = player_target_maxspeed;
}
else
{
if (player_y_diff < -player_target_maxspeed)
{
player_y_diff = -player_target_maxspeed;
}
}
player_y += player_y_diff;
}
unsigned short y = player_y / y_divisor;
spr_y_h[player_sprite] = y >> 8;
spr_y_l[player_sprite] = (unsigned char)y;
}
else
{
player_ready_y = 1;
}
if (player_x != player_x_target)
{
player_x_diff = (((signed short)player_x_target - (signed short)player_x)) / (signed short)player_target_divider;
if (player_x_diff == 0)
{
player_x = player_x_target;
}
else
{
if (player_x_diff > player_target_maxspeed)
{
player_x_diff = player_target_maxspeed;
}
else
{
if (player_x_diff < -player_target_maxspeed)
{
player_x_diff = -player_target_maxspeed;
}
}
player_x += player_x_diff;
}
set_sprite_position_x(player_sprite, player_x / x_divisor);
}
else
{
player_ready_x = 1;
}
player_ready = player_ready_x && player_ready_y;
}
// Player
void setup_player(unsigned short x, unsigned short y, unsigned char lives)
{
// Player bounds
player_x_min = 32 * x_divisor;
player_x_max = 336 * x_divisor;
player_y_min = 32 * y_divisor;
player_y_max = 244 * y_divisor;
// Player initial position
player_x = x * x_divisor;
player_y = y * y_divisor;
player_speed = player_speed_min;
player_xs = 0;
player_ys = 0;
player_hit = false;
player_lives = lives;
player_lives_changed = true;
player_respawn_timer = 0;
player_invincible_timer = 0;
player_invincible_flash = 0;
// Initialise player sprite
spr_index[player_sprite] = sprite_index_player_first;
enable_sprite(player_sprite, sprite_palette_player, sprite_size_player, true);
set_sprite_position(player_sprite, x, y);
// Trails
player_trail_timer = player_trail_frequency;
}
void player_destroyed()
{
play_sound(const_sound_player_explode);
add_explosion(0, 1);
add_explosion(1, 2);
spr_on[player_sprite] = false;
player_lives_changed = true;
if (player_lives > 0)
{
player_lives--;
player_respawn_timer = player_respawn_timeout;
}
}
void handle_player(bool allow_control)
{
// If player is currently dead and a respawn is scheduled
if (player_respawn_timer > 0)
{
player_hit = false;
// Decelerate player speed to minimum
if (player_speed > player_speed_min)
{
player_speed--;
}
// Decrement respawn timer
player_respawn_timer--;
// Respawn the player when timer reaches 0
if (player_respawn_timer == 0)
{
// Set player to spawn position
setup_player(player_spawn_x, player_spawn_y, player_lives);
// Enable invincibility and set timer
enable_sprite(player_sprite, sprite_palette_player, sprite_size_player, false);
player_invincible_timer = player_invincible_timeout;
}
return;
}
// If player is currently invincible
if (player_invincible_timer > 0)
{
// Ignore any collisions
player_hit = false;
// Decrement invincibility timer
player_invincible_timer--;
// Wait for invincibility timer to expire
if (player_invincible_timer == 0)
{
// Re-enable collision when invincibility runs out
enable_sprite(player_sprite, sprite_palette_player, sprite_size_player, true);
}
else
{
// Increment flash timer
player_invincible_flash++;
// Wait for invincibility flash timer to roll over
if (player_invincible_flash == 4)
{
// Reset timer
player_invincible_flash = 0;
// Flip player sprite visibility
spr_on[player_sprite] = !spr_on[player_sprite];
}
}
}
else
{
// If player is hit then destroy player
if (player_hit)
{
player_hit = false;
player_destroyed();
}
}
// Gradually reduce player move speed to zero
if (player_xs > 0)
{
player_xs--;
}
else if (player_xs < 0)
{
player_xs++;
}
if (player_ys > 0)
{
player_ys--;
}
else if (player_ys < 0)
{
player_ys++;
}
// Is player control activated?
if (allow_control)
{
// Use player directional inputs to increase/decrease velocity, enforcing max speed limits
if (CHECK_BIT(joystick[0], 0) && player_xs < player_max_speed)
{
player_xs += player_accel;
}
if (CHECK_BIT(joystick[0], 1) && player_xs > -player_max_speed)
{
player_xs -= player_accel;
}
if (CHECK_BIT(joystick[0], 2) && player_ys < player_max_speed)
{
player_ys += player_accel;
}
if (CHECK_BIT(joystick[0], 3) && player_ys > -player_max_speed)
{
player_ys -= player_accel;
}
// Use player boost input to increase/decrease player flight speed, enforcing max speed limits
if (CHECK_BIT(joystick[0], 4))
{
if (player_speed < player_speed_max)
{
player_speed++;
}
}
else
{
if (player_speed > player_speed_min)
{
player_speed--;
}
}
}
// Set player sprite image
spr_index[player_sprite] = (player_xs < -2 ? sprite_index_player_first + 2 : player_xs > 2 ? sprite_index_player_first + 3
: sprite_index_player_first);
// Integrate player move velocity
player_x += player_xs;
player_y += player_ys;
// Enforce player position limits when player is in control (disabled when not to allow ship to animate off screen)
if (allow_control)
{
// Enforce X minimum (left)
if (player_x < player_x_min)
{
player_x = player_x_min;
if (player_xs < 0)
{
player_xs = 0;
}
}
// Enforce X maximum (right)
else if (player_x > player_x_max)
{
player_x = player_x_max;
if (player_xs > 0)
{
player_xs = 0;
}
}
// Enforce Y minimum (top)
if (player_y < player_y_min)
{
player_y = player_y_min;
if (player_ys < 0)
{
player_ys = 0;
}
}
// Enforce Y maximum (bottom)
else if (player_y > player_y_max)
{
player_y = player_y_max;
if (player_ys > 0)
{
player_ys = 0;
}
}
}
// Set sprite position with low res coordinates
set_sprite_position(player_sprite, player_x / x_divisor, player_y / y_divisor);
// Decrease player trail timer
player_trail_timer--;
// Spawn player trail when timer expires
if (player_trail_timer <= 0)
{
// Generate next particle timer (emission rate)
unsigned char reduce = (player_speed / 8) + rand_uchar(0, 6);
player_trail_timer = player_trail_frequency - reduce;
if (player_trail_timer <= 0)
{
player_trail_timer = 0;
}
// Spawn a player trail entity
add_player_trail();
}
}

View File

@@ -0,0 +1,63 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Player routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
// Player
extern const signed char player_max_speed;
extern const unsigned char player_accel;
extern const unsigned char player_trail_frequency;
extern const unsigned char player_trail_speed;
extern const unsigned char player_trail_lifespan;
extern unsigned short player_x;
extern unsigned short player_y;
extern signed char player_xs;
extern signed char player_ys;
extern unsigned short player_x_min;
extern unsigned short player_x_max;
extern unsigned short player_y_min;
extern unsigned short player_y_max;
extern const unsigned char player_speed_min;
extern const unsigned char player_speed_max;
extern const unsigned char player_speed_warp;
extern unsigned char player_speed;
extern signed char player_trail_timer;
extern unsigned char player_lives;
extern unsigned char player_lives_changed;
extern const unsigned char player_invincible_timeout;
extern const unsigned char player_respawn_timeout;
extern unsigned char player_hit;
extern unsigned char player_ready;
extern unsigned char player_ready_x;
extern unsigned char player_ready_y;
extern unsigned short player_x_target;
extern unsigned short player_y_target;
extern signed short player_x_diff;
extern signed short player_y_diff;
extern void set_player_target(unsigned short x, unsigned short y, unsigned char divider, unsigned char maxspeed);
extern void move_player_to_target();
extern void setup_player(unsigned short x, unsigned short y, unsigned char lives);
extern void handle_player(bool allow_control);

View File

@@ -0,0 +1,107 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Trail routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/sprite.h"
#include "sprite_images.h"
#include "zorblaxx_app.h"
#include "zorblaxx_trails.h"
#include "zorblaxx_asteroids.h"
#include "zorblaxx_player.h"
#define const_trail_max 10
unsigned char trail_max = const_trail_max;
unsigned short trail_x[const_trail_max];
unsigned short trail_y[const_trail_max];
signed char trail_xs[const_trail_max];
signed char trail_ys[const_trail_max];
unsigned char trail_timer[const_trail_max];
unsigned short trail_y_max;
unsigned char trail_x_offset;
unsigned char trail_y_offset;
void setup_trails()
{
trail_y_max = 272 * y_divisor;
trail_x_offset = (4 * x_divisor);
trail_y_offset = (12 * y_divisor);
for (int t = trail_sprite_first; t < trail_sprite_first + trail_max; t++)
{
enable_sprite(t, sprite_palette_trails, sprite_size_trails, false);
spr_on[t] = false;
}
}
void add_player_trail()
{
for (unsigned char t = 0; t < trail_max; t++)
{
if (trail_timer[t] == 0)
{
unsigned char spread = 3 + (player_speed / 8);
trail_xs[t] = rand_schar(-spread, spread);
trail_ys[t] = player_trail_speed;
trail_x[t] = (player_x + trail_x_offset);
trail_y[t] = (player_y + trail_y_offset) - (player_trail_speed + player_speed);
trail_timer[t] = player_trail_lifespan;
unsigned char sprite = trail_sprite_first + t;
enable_sprite(sprite, sprite_palette_trails, sprite_size_trails, false);
spr_index[sprite] = sprite_index_trails_first;
return;
}
}
}
void handle_trails()
{
for (unsigned char t = 0; t < trail_max; t++)
{
if (trail_timer[t] > 0)
{
unsigned char sprite = trail_sprite_first + t;
trail_y[t] += trail_ys[t] + player_speed;
if ((trail_y[t] > trail_y_max) > 0)
{
spr_on[sprite] = false;
trail_timer[t] = 0;
continue;
}
trail_timer[t]--;
if (trail_timer[t] == 0)
{
spr_index[sprite]++;
if (spr_index[sprite] > sprite_index_trails_last)
{
spr_on[sprite] = false;
}
else
{
trail_timer[t] = player_trail_lifespan;
}
}
trail_x[t] += trail_xs[t];
set_sprite_position(sprite, trail_x[t] / x_divisor, trail_y[t] / y_divisor);
}
}
}

View File

@@ -0,0 +1,40 @@
/*============================================================================
Aznable OS - Zorblaxx demo application - Trail routines
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef ZORBLAXX_TRAILS_H
#define ZORBLAXX_TRAILS_H
// Trails
extern unsigned char trail_max;
extern unsigned short trail_x[];
extern unsigned short trail_y[];
extern signed char trail_xs[];
extern signed char trail_ys[];
extern unsigned char trail_timer[];
extern unsigned short trail_y_max;
extern void setup_trails();
extern void add_player_trail();
extern void handle_trails();
#endif

37
src/shared/Makefile Normal file
View File

@@ -0,0 +1,37 @@
SDCC=sdcc
CPU=z80
DATALOC=0xC000
OUT_DIR=build/
MAIN=os
OUTPUT=rom
SHARED_PATH=../shared/
SHARED_RELS_ALL=$(patsubst %.c,build/%.rel,$(wildcard $(SHARED_PATH)*.c)) # Get all c files from src/shared/ folder
IGNORE_SHARED_RELS=$(patsubst %, build/../shared/%.rel, $(IGNORE_SHARED)) # Format shared files to ignore correctly for filtering
SHARED_RELS=$(filter-out $(IGNORE_SHARED_RELS), $(SHARED_RELS_ALL)) # Filter out ignored shared files
PROJECT_RELS_ALL=$(patsubst %.c,build/%.rel,$(wildcard *.c)) # Get all c files from src/[project] folder
IGNORE_PROJECT_RELS=$(patsubst %, build/%.rel, $(IGNORE_PROJECT)) # Format project files to ignore correctly for filtering
PROJECT_RELS_FILTERED=$(filter-out $(IGNORE_PROJECT_RELS),$(PROJECT_RELS_ALL)) # Filter out ignored shared files
PROJECT_RELS=$(patsubst build/$(MAIN).rel,,$(PROJECT_RELS_FILTERED)) # Remove main c file
TARGET_RELS=$(patsubst build/$(MAIN).rel,,$(wildcard build/*.rel))
all: $(OUTPUT).bin
build/$(OUTPUT).ihx: $(PROJECT_RELS) $(SHARED_RELS)
$(SDCC) $(DEFINES) -m$(CPU) --data-loc $(DATALOC) -o $(OUT_DIR)$(OUTPUT).ihx $(MAIN).c $(TARGET_RELS)
build/%.rel: %.c
$(SDCC) $(DEFINES) -m$(CPU) --data-loc $(DATALOC) -o $(OUT_DIR) -c $<
$(OUTPUT).bin: build/$(OUTPUT).ihx
srec_cat $< -intel -o $@ -binary
rm build/$(OUTPUT).ihx
mv $(OUTPUT).bin bin/$(OUTPUT).bin
rm -f build/$(OUTPUT).*
clean:
rm -f build/*
rm -f bin/*

55
src/shared/music.c Normal file
View File

@@ -0,0 +1,55 @@
/*============================================================================
Aznable OS - Music engine (YM player)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.1
Date: 2022-01-07
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "../shared/sys.h"
#include "../shared/music.h"
#define const_music_track_max 32
unsigned char music_track_max = const_music_track_max;
unsigned char music_last_played = 255;
#include myPATH(../PROJECT_NAME/,music_tracks.h) // Include auto generated track array
void play_music(unsigned char track, unsigned char loop)
{
// Write track start address (3 bytes)
musicram[1] = (unsigned char)(music_track_address[track] >> 16);
musicram[2] = music_track_address[track] >> 8;
musicram[3] = music_track_address[track];
// Write start track instruction (2 for looping, 1 for single play)
musicram[0] = loop ? 2 : 1;
music_last_played = track;
}
void play_music_if(unsigned char track, unsigned char loop)
{
if (musicram[0] == 0 || music_last_played != track)
{
play_music(track, loop);
}
}
void stop_music()
{
// Send stop command
musicram[0] = 3;
}

30
src/shared/music.h Normal file
View File

@@ -0,0 +1,30 @@
/*============================================================================
Aznable OS - Music engine (YM player)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.1
Date: 2022-01-07
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef MUSIC_H
#define MUSIC_H
extern unsigned char music_track_max;
extern void play_music(unsigned char track, unsigned char loop);
extern void play_music_if(unsigned char track, unsigned char loop);
extern void stop_music();
#endif

View File

@@ -19,8 +19,8 @@
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
#include "sys.h"
#include "ps2.h"
// COMMAND KEYS
const char KEY_TAB = 0x0d;
@@ -37,51 +37,12 @@ const char KEY_CTRL = 0x63; // EXT 0 = LEFT, EXT 1 = RIGHT
const char KEY_1 = 0x16;
const char KEY_SPACE = 0x29;
// UNMAPPED COMMAND KEYS
// 0x7c, //55 KEY_KPASTERISK
// 0x05, //59 KEY_F1
// 0x06, //60 KEY_F2
// 0x04, //61 KEY_F3
// 0x0c, //62 KEY_F4
// 0x03, //63 KEY_F5
// 0x0b, //64 KEY_F6
// 0x83, //65 KEY_F7
// 0x0a, //66 KEY_F8
// 0x01, //67 KEY_F9
// 0x09, //68 KEY_F10
// 0x6c, //71 KEY_KP7
// 0x75, //72 KEY_KP8
// 0x7d, //73 KEY_KP9
// 0x7b, //74 KEY_KPMINUS
// 0x6b, //75 KEY_KP4
// 0x73, //76 KEY_KP5
// 0x74, //77 KEY_KP6
// 0x79, //78 KEY_KPPLUS
// 0x69, //79 KEY_KP1
// 0x72, //80 KEY_KP2
// 0x7a, //81 KEY_KP3
// 0x70, //82 KEY_KP0
// 0x71, //83 KEY_KPDOT
// 0x61, //86 KEY_102ND
// 0x78, //87 KEY_F11
// 0x07, //88 KEY_F12
// EXTENSION KEYS
const char KEY_UP = 0x75;
const char KEY_LEFT = 0x6b;
const char KEY_RIGHT = 0x74;
const char KEY_DOWN = 0x72;
// UNMAPPED EXTENSION KEYS
// EXT | 0x5a, //96 KEY_KPENTER
// EXT | 0x4a, //98 KEY_KPSLASH
// EXT | 0x6c, //102 KEY_HOME
// EXT | 0x7d, //104 KEY_PAGEUP
// EXT | 0x69, //107 KEY_END
// EXT | 0x7a, //109 KEY_PAGEDOWN
// EXT | 0x70, //110 KEY_INSERT
// EXT | 0x71, //111 KEY_DELETE
char kbd_UK[256] =
{
0, 0, // 0x00
@@ -197,7 +158,6 @@ char kbd_scan = 0;
char kbd_pressed;
char kbd_extend;
char kbd_ascii = 0;
char kbd_clock_index = 1;
char mse_lastclock = 0;
bool mse_changed = 1;
@@ -206,7 +166,6 @@ signed char mse_y;
signed char mse_w;
char mse_button1;
char mse_button2;
char mse_clock_index = 3;
char kbd_buffer[128];
char kbd_buffer_len = 0;
@@ -229,7 +188,7 @@ void get_ascii()
void handle_ps2()
{
bool kbd_clock = CHECK_BIT(ps2_key[kbd_clock_index], 2);
bool kbd_clock = CHECK_BIT(ps2_key[1], 2);
if (kbd_clock != kbd_lastclock)
{
for (char k = 0; k < 2; k++)
@@ -275,7 +234,7 @@ void handle_ps2()
}
kbd_lastclock = kbd_clock;
bool mse_clock = CHECK_BIT(ps2_mouse[mse_clock_index], 0);
bool mse_clock = CHECK_BIT(ps2_mouse[3], 0);
if (mse_clock != mse_lastclock)
{
mse_changed = 1;

106
src/shared/ps2.h Normal file
View File

@@ -0,0 +1,106 @@
/*============================================================================
Aznable OS - PS/2 interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.1
Date: 2021-10-20
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef PS2_H
#define PS2_H
// COMMAND KEYS
extern const char KEY_TAB;
extern const char KEY_CAPSLOCK;
extern const char KEY_ENTER;
extern const char KEY_BACKSPACE;
extern const char KEY_ESC;
extern const char KEY_LEFTSHIFT;
extern const char KEY_RIGHTSHIFT;
extern const char KEY_ALT;
extern const char KEY_CTRL;
// USEFUL KEYS
extern const char KEY_1;
extern const char KEY_SPACE;
// UNMAPPED COMMAND KEYS
// 0x7c, //55 KEY_KPASTERISK
// 0x05, //59 KEY_F1
// 0x06, //60 KEY_F2
// 0x04, //61 KEY_F3
// 0x0c, //62 KEY_F4
// 0x03, //63 KEY_F5
// 0x0b, //64 KEY_F6
// 0x83, //65 KEY_F7
// 0x0a, //66 KEY_F8
// 0x01, //67 KEY_F9
// 0x09, //68 KEY_F10
// 0x6c, //71 KEY_KP7
// 0x75, //72 KEY_KP8
// 0x7d, //73 KEY_KP9
// 0x7b, //74 KEY_KPMINUS
// 0x6b, //75 KEY_KP4
// 0x73, //76 KEY_KP5
// 0x74, //77 KEY_KP6
// 0x79, //78 KEY_KPPLUS
// 0x69, //79 KEY_KP1
// 0x72, //80 KEY_KP2
// 0x7a, //81 KEY_KP3
// 0x70, //82 KEY_KP0
// 0x71, //83 KEY_KPDOT
// 0x61, //86 KEY_102ND
// 0x78, //87 KEY_F11
// 0x07, //88 KEY_F12
// EXTENSION KEYS
extern const char KEY_UP;
extern const char KEY_LEFT;
extern const char KEY_RIGHT;
extern const char KEY_DOWN;
// UNMAPPED EXTENSION KEYS
// EXT | 0x5a, //96 KEY_KPENTER
// EXT | 0x4a, //98 KEY_KPSLASH
// EXT | 0x6c, //102 KEY_HOME
// EXT | 0x7d, //104 KEY_PAGEUP
// EXT | 0x69, //107 KEY_END
// EXT | 0x7a, //109 KEY_PAGEDOWN
// EXT | 0x70, //110 KEY_INSERT
// EXT | 0x71, //111 KEY_DELETE
extern char kbd_shift_left;
extern char kbd_shift_right;
extern char kbd_scan;
extern char kbd_pressed;
extern char kbd_extend;
extern char kbd_ascii;
extern bool mse_changed;
extern signed char mse_x;
extern signed char mse_y;
extern signed char mse_w;
extern char mse_button1;
extern char mse_button2;
extern char kbd_buffer[128];
extern char kbd_buffer_len;
extern bool kbd_down[256];
extern void get_ascii();
extern void handle_ps2();
#endif

46
src/shared/sound.c Normal file
View File

@@ -0,0 +1,46 @@
/*============================================================================
Aznable OS - Sound engine (M5205 sample player)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-12-20
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "sys.h"
#include "sound.h"
#define const_sound_sample_max 32
unsigned char sound_sample_max = const_sound_sample_max;
#include myPATH(../PROJECT_NAME/,sound_samples.h) // Include auto generated track array
void play_sound(unsigned char sample)
{
// Write sample start address (2 bytes)
sndram[1] = sound_sample_address[sample] >> 8;
sndram[0] = sound_sample_address[sample];
// Write sample length (2 bytes)
unsigned short end = sound_sample_address[sample] + sound_sample_length[sample];
sndram[5] = end >> 8;
sndram[4] = end;
// Write play instruction
sndram[8] = 1;
}
void set_sound_volume(unsigned char volume)
{
// Write sample volume
sndram[12] = volume;
}

29
src/shared/sound.h Normal file
View File

@@ -0,0 +1,29 @@
/*============================================================================
Aznable OS - Sound engine (M5205 sample player)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-12-20
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef SOUND_H
#define SOUND_H
extern unsigned char sound_sample_max;
extern void play_sound(unsigned char sample);
extern void set_sound_volume(unsigned char volume);
#endif

96
src/shared/sprite.c Normal file
View File

@@ -0,0 +1,96 @@
/*============================================================================
Aznable OS - Casval (sprite engine)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "sys.h"
#include "sprite.h"
#define const_sprite_max 32
unsigned char sprite_max = const_sprite_max;
unsigned char spr_x_l[const_sprite_max];
unsigned char spr_x_h[const_sprite_max];
unsigned char spr_y_l[const_sprite_max];
unsigned char spr_y_h[const_sprite_max];
bool spr_on[const_sprite_max];
bool spr_collide[const_sprite_max];
unsigned char spr_palette_index[const_sprite_max];
unsigned char spr_index[const_sprite_max];
unsigned char spr_size[const_sprite_max];
unsigned char spr_highbits[const_sprite_max]; // Temp cache of high bits excluding upper 2 Y bits
void set_sprite_position(unsigned char sprite, unsigned short x, unsigned short y)
{
spr_x_h[sprite] = x >> 8;
spr_x_l[sprite] = (unsigned char)x;
spr_y_h[sprite] = y >> 8;
spr_y_l[sprite] = (unsigned char)y;
}
void set_sprite_position_x(unsigned char sprite, unsigned short x)
{
spr_x_h[sprite] = x >> 8;
spr_x_l[sprite] = (unsigned char)x;
}
void update_sprites()
{
unsigned char s = 0;
for (unsigned char sprite = 0; sprite < sprite_max; sprite++)
{
if (spr_on[sprite])
{
// Set sprite properties
spriteram[s++] = spr_highbits[sprite] | spr_y_h[sprite]; // Enabled (1 bit) + Collide (1 bit) + Size (2 bits) + Palette Index (2 bits) + Position Y (upper 2 bits)
spriteram[s++] = spr_y_l[sprite]; // Position Y (lower 8 bits)
spriteram[s++] = spr_index[sprite] << 2 | spr_x_h[sprite]; // Sprite Index (6 bits) + Position X (upper 2 bits)
spriteram[s++] = spr_x_l[sprite]; // Position X (lower 8 bits)
}
else
{
// Clear first sprite byte to disable
spriteram[s] = 0;
s += 4;
}
}
}
void enable_sprite(unsigned char sprite, unsigned char palette_index, unsigned char size, unsigned char collide)
{
spr_on[sprite] = 1;
spr_collide[sprite] = collide;
spr_palette_index[sprite] = palette_index;
spr_size[sprite] = size;
spr_highbits[sprite] = 1 << 7 | collide << 6 | palette_index << 4 | size << 2;
}
void clear_sprites()
{
for (unsigned char sprite = 0; sprite < sprite_max; sprite++)
{
spr_on[sprite] = 0;
}
}
void clear_sprites_range(unsigned char first, unsigned char last)
{
for (unsigned char sprite = first; sprite <= last; sprite++)
{
spr_on[sprite] = 0;
}
}

47
src/shared/sprite.h Normal file
View File

@@ -0,0 +1,47 @@
/*============================================================================
Aznable OS - Casval (sprite engine)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef SPRITE_H
#define SPRITE_H
extern unsigned char sprite_max;
extern unsigned char spr_x_l[];
extern unsigned char spr_x_h[];
extern unsigned char spr_y_l[];
extern unsigned char spr_y_h[];
extern bool spr_on[];
extern bool spr_collide[];
extern unsigned char spr_palette_index[];
extern unsigned char spr_index[];
extern unsigned char spr_size[];
extern void set_sprite_position(unsigned char sprite, unsigned short x, unsigned short y);
extern void set_sprite_position_x(unsigned char sprite, unsigned short x);
extern void update_sprites();
extern void enable_sprite(unsigned char sprite, unsigned char palette_index, unsigned char size, unsigned char collide);
extern void clear_sprites();
extern void clear_sprites_range(unsigned char first, unsigned char last);
#endif

62
src/shared/starfield.c Normal file
View File

@@ -0,0 +1,62 @@
/*============================================================================
Aznable OS - Moroboshi (starfield)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "sys.h"
void enable_starfield()
{
starfield1[0] = 1;
starfield2[0] = 1;
starfield3[0] = 1;
}
void disable_starfield()
{
starfield1[0] = 0;
starfield2[0] = 0;
starfield3[0] = 0;
}
void set_starfield_speed_x(float speed)
{
unsigned char dir = (speed < 0) << 7;
unsigned short mag = (unsigned short)abs(speed * 256);
starfield3[1] = dir | mag >> 8;
starfield3[2] = (unsigned char)mag;
mag = mag << 1;
starfield2[1] = dir | mag >> 8;
starfield2[2] = (unsigned char)mag;
mag = mag << 1;
starfield1[1] = dir | mag >> 8;
starfield1[2] = (unsigned char)mag;
}
void set_starfield_speed_y(float speed)
{
unsigned char dir = (speed < 0) << 7;
unsigned short mag = (unsigned short)abs(speed * 256);
starfield3[3] = dir | mag >> 8;
starfield3[4] = (unsigned char)mag;
mag = mag << 1;
starfield2[3] = dir | mag >> 8;
starfield2[4] = (unsigned char)mag;
mag = mag << 1;
starfield1[3] = dir | mag >> 8;
starfield1[4] = (unsigned char)mag;
}

32
src/shared/starfield.h Normal file
View File

@@ -0,0 +1,32 @@
/*============================================================================
Aznable OS - Moroboshi (starfield)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef STARFIELD_H
#define STARFIELD_H
extern void enable_starfield();
extern void disable_starfield();
extern void set_starfield_speed_x(float speed);
extern void set_starfield_speed_y(float speed);
#endif

View File

@@ -2,8 +2,8 @@
Aznable OS - System interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.1
Date: 2021-10-20
Version: 1.2
Date: 2021-11-27
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
@@ -19,33 +19,18 @@
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
// Memory mapped IO
// - Inputs
unsigned char __at(0x6000) input0;
unsigned char __at(0x7000) joystick[24];
unsigned char __at(0x7100) analog_l[12];
unsigned char __at(0x7200) analog_r[12];
unsigned char __at(0x7300) paddle[6];
unsigned char __at(0x7400) spinner[12];
unsigned char __at(0x7500) ps2_key[2];
unsigned char __at(0x7600) ps2_mouse[6];
unsigned char __at(0x7700) timestamp[5];
unsigned char __at(0x7800) timer[2];
// - Graphics RAM
unsigned char __at(0x8000) chram[2048];
unsigned char __at(0x8800) fgcolram[2048];
unsigned char __at(0x9000) bgcolram[2048];
#include "sys.h"
// Character map
const unsigned char chram_cols = 64;
const unsigned char chram_rows = 32;
unsigned int chram_size;
unsigned short chram_size;
// Hardware inputs
bool hsync;
@@ -57,15 +42,18 @@ bool hblank_last;
bool vblank;
bool vblank_last;
// Macros
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
#define SET_BIT(var,pos) ((var) |= (1 << (pos)))
#define CLEAR_BIT(var,pos) ((var) &= ~(1 << (pos)))
#define VBLANK_RISING (vblank && !vblank_last)
#define VSYNC_RISING (vsync && !vsync_last)
#define HBLANK_RISING (hblank && !hblank_last)
#define HSYNC_RISING (hsync && !hsync_last)
// Helper functions
unsigned char rand_uchar(unsigned char lower, unsigned char upper)
{
return (rand() % (upper - lower + 1)) + lower;
}
// Application state
char state = 0;
char nextstate = 0;
unsigned short rand_ushort(unsigned short lower, unsigned short upper)
{
return (rand() % (upper - lower + 1)) + lower;
}
signed char rand_schar(signed char lower, signed char upper)
{
return (rand() % (upper - lower + 1)) + lower;
}

110
src/shared/sys.h Normal file
View File

@@ -0,0 +1,110 @@
/*============================================================================
Aznable OS - System interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.2
Date: 2021-11-27
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef SYS_H
#define SYS_H
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
// Memory mapped IO
// - Inputs
unsigned char __at(0x8000) input0;
unsigned char __at(0x8100) joystick[24];
unsigned char __at(0x8200) analog_l[12];
unsigned char __at(0x8300) analog_r[12];
unsigned char __at(0x8400) paddle[6];
unsigned char __at(0x8500) spinner[12];
unsigned char __at(0x8600) ps2_key[2];
unsigned char __at(0x8700) ps2_mouse[6];
unsigned char __at(0x8800) timestamp[5];
unsigned char __at(0x8900) timer[2];
unsigned char __at(0x8A00) starfield1[5];
unsigned char __at(0x8A10) starfield2[5];
unsigned char __at(0x8A20) starfield3[5];
unsigned char __at(0x8A30) system_pause;
unsigned char __at(0x8A31) system_menu;
// - Casval (character map)
unsigned char __at(0x9800) chram[2048];
unsigned char __at(0xA000) fgcolram[2048];
unsigned char __at(0xA800) bgcolram[2048];
// - Comet (sprite engine)
unsigned char __at(0xB000) spriteram[512];
unsigned char __at(0xB400) spritecollisionram[32];
// - Zechs (tilemap)
unsigned char __at(0x8C00) tilemapctl[4];
unsigned char __at(0x8C10) tilemapram[1024];
// - Charles (sound)
unsigned char __at(0x8B00) sndram[16];
// - Deikun (music)
unsigned char __at(0x8B10) musicram[4];
// Character map
extern const unsigned char chram_cols;
extern const unsigned char chram_rows;
extern unsigned short chram_size;
// Hardware inputs
extern bool hsync;
extern extern bool hsync_last;
extern bool vsync;
extern bool vsync_last;
extern bool hblank;
extern bool hblank_last;
extern bool vblank;
extern bool vblank_last;
// INPUT 0 bits
#define INPUT_HBLANK 5
#define INPUT_VBLANK 4
// Macros
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
#define SET_BIT(var, pos) ((var) |= (1 << (pos)))
#define CLEAR_BIT(var, pos) ((var) &= ~(1 << (pos)))
#define VBLANK_RISING (vblank && !vblank_last)
#define VSYNC_RISING (vsync && !vsync_last)
#define HBLANK_RISING (hblank && !hblank_last)
#define HSYNC_RISING (hsync && !hsync_last)
#define VBLANK_FALLING (!vblank && vblank_last)
#define VSYNC_FALLING (!vsync && vsync_last)
#define HBLANK_FALLING (!hblank && hblank_last)
#define HSYNC_FALLING (!hsync && hsync_last)
#define GET_TIMER ((unsigned short)timer[1] << 8) | (unsigned char)timer[0]
// Auto include handling
#define myIDENT(x) x
#define myXSTR(x) #x
#define mySTR(x) myXSTR(x)
#define myPATH(x,y) mySTR(myIDENT(x)myIDENT(y))
// Helper functions
extern unsigned char rand_uchar(unsigned char lower, unsigned char upper);
extern unsigned short rand_ushort(unsigned short lower, unsigned short upper);
extern signed char rand_schar(signed char lower, signed char upper);
#endif

68
src/shared/tilemap.c Normal file
View File

@@ -0,0 +1,68 @@
/*============================================================================
Aznable OS - Zechs (tilemap engine)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2022-01-03
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#include "sys.h"
#include "tilemap.h"
signed char tilemap_offset_x = 0;
signed char tilemap_offset_y = 0;
void update_tilemap_offset()
{
tilemapctl[0] = tilemap_offset_x;
tilemapctl[1] = tilemap_offset_y;
}
void scroll_tilemap_left()
{
tilemapctl[2] = 1;
while (tilemapctl[2] != 0)
{
}
}
void scroll_tilemap_right()
{
tilemapctl[2] = 2;
while (tilemapctl[2] != 0)
{
}
}
void scroll_tilemap_up()
{
tilemapctl[2] = 3;
while (tilemapctl[2] != 0)
{
}
}
void scroll_tilemap_down()
{
tilemapctl[2] = 4;
while (tilemapctl[2] != 0)
{
}
}
void clear_tilemap()
{
tilemapctl[2] = 5;
while (tilemapctl[2] != 0)
{
}
}

34
src/shared/tilemap.h Normal file
View File

@@ -0,0 +1,34 @@
/*============================================================================
Aznable OS - Zechs (tilemap engine)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2022-01-03
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef TILEMAP_H
#define TILEMAP_H
extern signed char tilemap_offset_x;
extern signed char tilemap_offset_y;
extern void update_tilemap_offset();
extern void scroll_tilemap_left();
extern void scroll_tilemap_right();
extern void scroll_tilemap_up();
extern void scroll_tilemap_down();
extern void clear_tilemap();
#endif

View File

@@ -19,26 +19,16 @@
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
#pragma once
#include "sys.c"
#include "sys.h"
#include "ui.h"
char asc_0 = 48;
char asc_1 = 49;
#define char_corner_round_tl 149
#define char_corner_round_tr 137
#define char_corner_round_bl 138
#define char_corner_round_br 139
#define char_line_h 131
#define char_line_v 130
#define char_t_up 177
#define char_dot 27
#define char_cross 155
// Set all character RAM to specified character
void clear_chars(char c)
{
for (unsigned int p = 0; p < chram_size; p++)
for (unsigned short p = 0; p < chram_size; p++)
{
chram[p] = c;
fgcolram[p] = c;
@@ -46,10 +36,18 @@ void clear_chars(char c)
}
}
void clear_char_area(char c, unsigned char tx, unsigned char ty, unsigned char bx, unsigned char by)
{
for (char y = ty; y <= by; y++)
{
write_char_row(c, 0, tx, y, (bx - tx) + 1);
}
}
// Set all character background colours to specified
void clear_bgcolor(char color)
{
for (unsigned int p = 0; p < chram_size; p++)
for (unsigned short p = 0; p < chram_size; p++)
{
bgcolram[p] = color;
}
@@ -58,7 +56,7 @@ void clear_bgcolor(char color)
// Write string to character RAM
void write_string(const char *string, char color, unsigned char x, unsigned char y)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
unsigned char l = strlen(string);
for (char c = 0; c < l; c++)
{
@@ -71,7 +69,7 @@ void write_string(const char *string, char color, unsigned char x, unsigned char
// Write formatted string to character RAM (signed char data)
void write_stringfs(const char *format, char color, unsigned char x, unsigned char y, signed char data)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
char temp[30];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
@@ -88,9 +86,9 @@ void write_stringfs(const char *format, char color, unsigned char x, unsigned ch
}
// Write formatted string to character RAM (unsigned char data)
void write_stringf(const char *format, char color, unsigned char x, unsigned char y, char data)
void write_stringf(const char *format, char color, unsigned char x, unsigned char y, unsigned char data)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
char temp[30];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
@@ -109,7 +107,7 @@ void write_stringf(const char *format, char color, unsigned char x, unsigned cha
// Write formatted string to character RAM (unsigned short data)
void write_stringf_ushort(const char *format, char color, unsigned char x, unsigned char y, unsigned short data)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
char temp[40];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
@@ -126,9 +124,9 @@ void write_stringf_ushort(const char *format, char color, unsigned char x, unsig
}
// Write formatted string to character RAM (signed short data)
void write_stringf_short(const char *format, char color, unsigned char x, unsigned char y, short data)
void write_stringf_short(const char *format, char color, unsigned char x, unsigned char y, signed short data)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
char temp[40];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
@@ -147,7 +145,7 @@ void write_stringf_short(const char *format, char color, unsigned char x, unsign
// Write formatted string to character RAM (unsigned long data)
void write_stringf_ulong(const char *format, char color, unsigned char x, unsigned char y, unsigned long data)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
char temp[40];
sprintf(temp, format, data);
unsigned char l = strlen(temp);
@@ -166,7 +164,7 @@ void write_stringf_ulong(const char *format, char color, unsigned char x, unsign
// Write single char to character RAM and colour RAM
void write_char(unsigned char c, char color, unsigned char x, unsigned char y)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
chram[p] = c;
fgcolram[p] = color;
}
@@ -174,7 +172,7 @@ void write_char(unsigned char c, char color, unsigned char x, unsigned char y)
// Write row of consecutive chars to character RAM and colour RAM
void write_char_row(unsigned char c, char color, unsigned char x, unsigned char y, unsigned char count)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
for (char b = 0; b < count; b++)
{
chram[p] = c;
@@ -186,21 +184,21 @@ void write_char_row(unsigned char c, char color, unsigned char x, unsigned char
// Set colour of single char
void set_fgcolour(char color, char x, char y)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
fgcolram[p] = color;
}
// Set background colour of single char
void set_bgcolour(char color, char x, char y)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
bgcolram[p] = color;
}
// Write row of consecutive chars to character RAM and colour RAM
void write_bgcol_row(char color, unsigned char x, unsigned char y, unsigned char count)
{
unsigned int p = (y * chram_cols) + x;
unsigned short p = (y * chram_cols) + x;
for (char b = 0; b < count; b++)
{
bgcolram[p] = color;
@@ -285,13 +283,6 @@ void fill(char tx, char ty, char bx, char by, char c, char color)
write_char_row(c, color, tx, y, (bx - tx) + 1);
}
}
void fill_bgcolor(char tx, char ty, char bx, char by, char bgcolor)
{
for (char y = ty; y <= by; y++)
{
write_bgcol_row(bgcolor, tx, y, (bx - tx) + 1);
}
}
void fill_bgcol(char tx, char ty, char bx, char by, char color)
{
for (char y = ty; y <= by; y++)

100
src/shared/ui.h Normal file
View File

@@ -0,0 +1,100 @@
/*============================================================================
Aznable OS - User interface functions
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.1
Date: 2021-07-15
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 <http://www.gnu.org/licenses/>.
===========================================================================*/
#ifndef UI_H
#define UI_H
extern char asc_0;
extern char asc_1;
#define char_corner_round_tl 149
#define char_corner_round_tr 137
#define char_corner_round_bl 138
#define char_corner_round_br 139
#define char_line_h 131
#define char_line_v 130
#define char_t_up 177
#define char_dot 27
#define char_cross 155
// Set all character RAM to specified character
extern void clear_chars(char c);
// Set area of character RAM to specified character
extern void clear_char_area(char c, unsigned char tx, unsigned char ty, unsigned char bx, unsigned char by);
// Set all character background colours to specified
extern void clear_bgcolor(char color);
// Write string to character RAM
extern void write_string(const char *string, char color, unsigned char x, unsigned char y);
// Write formatted string to character RAM (signed char data)
extern void write_stringfs(const char *format, char color, unsigned char x, unsigned char y, signed char data);
// Write formatted string to character RAM (unsigned char data)
extern void write_stringf(const char *format, char color, unsigned char x, unsigned char y, unsigned char data);
// Write formatted string to character RAM (unsigned short data)
extern void write_stringf_ushort(const char *format, char color, unsigned char x, unsigned char y, unsigned short data);
// Write formatted string to character RAM (signed short data)
extern void write_stringf_short(const char *format, char color, unsigned char x, unsigned char y, signed short data);
// Write formatted string to character RAM (unsigned long data)
extern void write_stringf_ulong(const char *format, char color, unsigned char x, unsigned char y, unsigned long data);
// Write single char to character RAM and colour RAM
extern void write_char(unsigned char c, char color, unsigned char x, unsigned char y);
// Write row of consecutive chars to character RAM and colour RAM
extern void write_char_row(unsigned char c, char color, unsigned char x, unsigned char y, unsigned char count);
// Set colour of single char
extern void set_fgcolour(char color, char x, char y);
// Set background colour of single char
extern void set_bgcolour(char color, char x, char y);
// Write row of consecutive chars to character RAM and colour RAM
extern void write_bgcol_row(char color, unsigned char x, unsigned char y, unsigned char count);
// Write grouped bits to character RAM
extern void write_bits(char bits[], char multi, unsigned char first, unsigned char length, char color, unsigned char x, unsigned char y);
// Draw box outline with specified character
extern void box(unsigned char tx, unsigned char ty, unsigned char bx, unsigned char by, char c, char color);
// Draw UI panel
extern void panel(char tx, char ty, char bx, char by, char color);
// Shaded panel
extern void panel_shaded(char tx, char ty, char bx, char by, char color_high, char color1, char color2);
extern void fill(char tx, char ty, char bx, char by, char c, char color);
extern void fill_bgcol(char tx, char ty, char bx, char by, char color);
// Draw page border
extern void page_border(char color);
extern void draw_charactermap();
#endif