Fix game mode

This commit is contained in:
hkz 2025-10-13 19:36:20 +02:00
commit 735513e5c8
4 changed files with 41 additions and 34 deletions

View file

@ -265,6 +265,7 @@ SetTile$:
lda TileNum_Offset_Map,x
adc zp:P_TYPE$
sta VDP_MEM
nop
inx
dey
bne SetTile$

View file

@ -39,10 +39,13 @@ static state_page_data* state_page = (state_page_data*)STATE_PAGE;
static shared_page_data *shared_page = (shared_page_data*)SHARED_PAGE;
static uint8_t text_buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
__attribute__((interrupt)) void irq_handler(void);
void main(void) {
uint16_t moves_count = 0;
uint16_t score = 0;
int8_t done = 0;
uint8_t read_key;
__disable_interrupts(); // Make sure the interrupts are disabled
@ -59,7 +62,7 @@ void main(void) {
vdp_switch_nt(0); // Make sure VDP shows the gamegrid
// Setup the IRQ handler
POKEW(IRQ_HANDLER_ADDRESS, (uint16_t)vdp_irq_handler);
POKEW(IRQ_HANDLER_ADDRESS, (uint16_t)irq_handler);
// Reset the game, calculate the initial score depending on which tiles we randomly get
score = reset_game();
@ -93,66 +96,53 @@ void main(void) {
vdp_redraw_tiles(get_front_grid());
//__enable_interrupts();
__enable_interrupts();
while(1) { // Game loop
lfsr_update();
__disable_interrupts();
switch(read_kb()) {
case K_UP:
__disable_interrupts();
SND_TAP();
vdp_draw_joystick(JS_POS_UP);
done = step_game(GAME_STEP_UP);
//__enable_interrupts();
break;
case K_DOWN:
__disable_interrupts();
SND_TAP();
vdp_draw_joystick(JS_POS_DOWN);
done = step_game(GAME_STEP_DOWN);
//__enable_interrupts();
break;
case K_LEFT:
__disable_interrupts();
SND_TAP();
vdp_draw_joystick(JS_POS_LEFT);
done = step_game(GAME_STEP_LEFT);
//__enable_interrupts();
break;
case K_RIGHT:
__disable_interrupts();
SND_TAP();
vdp_draw_joystick(JS_POS_RIGHT);
done = step_game(GAME_STEP_RIGHT);
//__enable_interrupts();
break;
case K_CTRL_R:
__disable_interrupts();
snd_mod_button();
//__enable_interrupts();
score = 0; // We'll reset the score
done = -1;
break;
case K_CTRL_S: // The following two will return early
__disable_interrupts();
snd_mod_button();
//__enable_interrupts();
memcpy((void*)(state_page->save_grid), get_front_grid(), GRID_SIDE * GRID_SIDE);
state_page->saved_moves_count = moves_count;
shared_page->master_command = MASTER_COMMAND_SAVE;
case K_CTRL_L:
__disable_interrupts();
snd_mod_button();
//__enable_interrupts();
shared_page->next_module_idx = MODULE_GAME;
gad->mode = GAME_MODE_LOAD;
__disable_interrupts();
return;
default:
__enable_interrupts();
continue; // Do nothing, loop again
}
@ -161,9 +151,7 @@ void main(void) {
num_to_decbuf(moves_count, 5, text_buf); // Moves count
decbuf_to_ascii(5, text_buf);
__disable_interrupts();
vdp_print_string(0, MOVES_TEXT_X, MOVES_TEXT_Y, (char*)text_buf);
//__enable_interrupts();
// If we have won, or we got a reset request, break out of this loop
if(done) {
@ -171,7 +159,6 @@ void main(void) {
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
__disable_interrupts();
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
break;
@ -189,11 +176,11 @@ void main(void) {
// Draw the score
num_to_decbuf(score, 5, text_buf); // Score
decbuf_to_ascii(5, text_buf);
__disable_interrupts();
vdp_print_string(0, SCORE_TEXT_X, SCORE_TEXT_Y, (char*)text_buf);
vdp_redraw_tiles(get_front_grid());
vdp_draw_joystick(JS_POS_CENTER);
//__enable_interrupts();
__enable_interrupts();
}
dld->mode = (done > 0) ? DLOG_MODE_WIN : DLOG_MODE_LOSE;
@ -207,3 +194,8 @@ void main(void) {
return;
}
__attribute__((interrupt)) void irq_handler(void) {
vdp_write_interleaved_sat();
}

View file

@ -14,6 +14,6 @@ void vdp_set_sprite_tile(uint8_t sprite_number, uint8_t tile_idx);
void vdp_switch_nt(uint8_t nt_idx);
void vdp_print_string(uint8_t nt_idx, uint8_t x, uint8_t y, char *str);
void vdp_set_tile(uint8_t nt_idx, uint8_t x, uint8_t y, uint8_t tile_idx);
void vdp_irq_handler(void);
void vdp_write_interleaved_sat(void);
#endif /* _VDP_UTILS_HEADER_ */

View file

@ -54,9 +54,11 @@ ShiftOffset$:
; Setup the VDP to write into VRAM
lda zp:T_VADD_L$
sta VDP_REG
nop
lda zp:T_VADD_H$
ora #0x40
sta VDP_REG
nop
rts
@ -88,6 +90,7 @@ P_X$: .equ _Zp+0
lda zp:P_TILE$
sta VDP_MEM
nop
EOS$:
rts
@ -126,6 +129,8 @@ NextChar$:
sec
sbc #0x20
sta VDP_MEM
nop
nop
iny
bne NextChar$
@ -175,6 +180,7 @@ P_DATA_L$: .equ _Zp+0
CopyLoop$:
lda (zp:P_DATA_L$),y
sta VDP_MEM
nop
iny
bne SkipHIncr$ ; Check if we did overflow. In case, increment the high byte of the address
inc zp:P_DATA_H$
@ -231,6 +237,7 @@ P_DLEN_L$: .equ _Zp+0
CopyLoop$:
lda zp:T_FILLVAL$
sta VDP_MEM
nop
dec zp:P_DLEN_L$
lda zp:P_DLEN_L$
@ -253,20 +260,28 @@ CopyLoop$:
vdp_detect:
lda #0x00
sta VDP_REG
nop
lda #0x40
sta VDP_REG
nop
lda #0x55
sta VDP_MEM
nop
lda #0xAA
sta VDP_MEM
nop
lda #0x00
sta VDP_REG
nop
sta VDP_REG
nop
eor VDP_MEM
nop
eor VDP_MEM
nop
cmp #0xFF
beq VdpFound$
@ -296,7 +311,7 @@ HideLoop$:
bne HideLoop$
; Make sure the table gets updated in memory
jsr _vdp_write_interleaved_sat
jsr vdp_write_interleaved_sat
rts
@ -372,8 +387,10 @@ vdp_switch_nt:
lsr a
lsr a
sta VDP_REG
nop
lda #0x82
sta VDP_REG
nop
rts
;;; vdp_write_registers:
@ -395,20 +412,14 @@ P_REG_L$: .equ _Zp+0
RegLoop$:
lda (zp:P_REG_L$),y
sta VDP_REG
nop
iny
cpy #16
bne RegLoop$
rts
vdp_irq_handler:
lda VDP_REG ; Clear the interrupt
jsr _vdp_write_interleaved_sat
rti
;;; _vdp_write_interleaved_sat:
;;; vdp_write_interleaved_sat:
;;; Updates SAT at 0x300 with sprite multiplexing
;;; Parameters: none
;;;
@ -418,7 +429,7 @@ vdp_irq_handler:
;;; - A, Y, X
;;; - Zp 1, 2, 3, 4, 5, 6, 7
;;;
_vdp_write_interleaved_sat:
vdp_write_interleaved_sat:
T_COUNT$: .equ _Zp+7
T_SATB_IDX$: .equ _Zp+6
T_DEST_H$: .equ _Zp+5
@ -427,6 +438,9 @@ T_DLEN_H$: .equ _Zp+3
T_DLEN_L$: .equ _Zp+2
T_DATA_H$: .equ _Zp+1
T_DATA_L$: .equ _Zp+0
lda VDP_REG ; FIXME: Put this here temporarily as this is often
; used in interrupt handling, and we need to clear
; the interrupt
lda #0x00
sta zp:T_DEST_L$
@ -589,7 +603,7 @@ CurrentByteTableOffset:
.public vdp_print_string
.public vdp_set_tile
.public vdp_point_to_vram_xy
.public vdp_irq_handler
.public vdp_write_interleaved_sat
.public SpriteAttributeTable ; We'll need to set change visibility and values
.public NT_P0, NT_P1