uploaded files
This commit is contained in:
221
src/Main.c
Normal file
221
src/Main.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
// Function: Retro Handheld Tetris Game Console source code, including game GUI,
|
||||
// Tetris, Snake, Classic Racing, and Obstacle Shooting games.
|
||||
|
||||
v1.0:
|
||||
2014-7-26 00:00:00 : Completed the basic model for the Tetris game;
|
||||
2014-7-28 02:12:03 : Changed the temporary delay-based keyboard scanning to external interrupt status detection;
|
||||
2014-7-28 20:40:37 : Implemented Tetris scoring and score display functions;
|
||||
2014-8-1 01:01:54 : Merged and integrated the previously completed Snake game code;
|
||||
2014-8-2 17:04:25 : Organized temporary source code to standardize project files;
|
||||
2014-8-3 23:50:49 : Built the basic model for the game selection screen and completed the screen transition effect;
|
||||
2014-8-5 00:50:04 : Improved LED dot-matrix low-level driver, added software PWM to adjust screen brightness;
|
||||
2014-8-7 00:53:35 : Completed the racing game; used PWM layered scanning for screen display to create contrast;
|
||||
2014-8-8 02:16:44 : Completed the racing game preview screen and merged all three games;
|
||||
2014-8-12 01:47:07 : Changed line-by-line scanning to point-by-point scanning for uniform display brightness; added brightness adjustment;
|
||||
2014-9-9 00:32:40 : Modified and optimized several details;
|
||||
|
||||
v1.1:
|
||||
2014-9-18 0:57:23 : Re-laid out the circuit, corrected unreasonable design parts, and prepared for PCB production;
|
||||
2014-9-19 22:02:36 : Added game sound effects with software-controlled mute switch;
|
||||
2014-9-21 14:59:39 : Added three mini digital tubes to display the game score in real-time, sharing the parallel data port with the dot-matrix;
|
||||
~~~~~~~~~~~ Note forgotten ~~~~~~~~~~~
|
||||
2014-10-20 21:30:15 : Added shooting game and modularized the GUI to simplify the workflow.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
volatile uint8 data keypad = K_NULL; // Keypad status
|
||||
volatile uint8 data keycont = 0; // Keypad debounce timer
|
||||
volatile uint16 data tms = 0; // 1ms T0 timer
|
||||
bit key_state = 0; // Key state
|
||||
|
||||
uint16 data speeds = 0; // Game speed
|
||||
uint16 data scores = 0; // Game score
|
||||
bit Glife = 1; // Game life status
|
||||
bit sound_ON = 1; // Sound effect switch
|
||||
uint8 data duty = 80; // PWM, default brightness
|
||||
uint8 data DispRAM[16]={0}; // Display RAM
|
||||
uint8 code bitman[8]={1,2,4,8,16,32,64,128}; // Bitmask for locating bits 0-7
|
||||
|
||||
uint8 code num[10][5]= // Yang code
|
||||
{
|
||||
{0x7,0x5,0x5,0x5,0x7},
|
||||
{0x2,0x6,0x2,0x2,0x7},
|
||||
{0x7,0x1,0x7,0x4,0x7},
|
||||
{0x7,0x1,0x7,0x1,0x7},
|
||||
{0x5,0x5,0x7,0x1,0x1},
|
||||
{0x7,0x4,0x7,0x1,0x7},
|
||||
{0x7,0x4,0x7,0x5,0x7},
|
||||
{0x7,0x1,0x1,0x1,0x1},
|
||||
{0x7,0x5,0x7,0x5,0x7},
|
||||
{0x7,0x5,0x7,0x1,0x7}
|
||||
};
|
||||
|
||||
/*********************PORT_INIT********************/
|
||||
void Port_Init()
|
||||
{
|
||||
P0M0 = 0Xff;
|
||||
P0M1 = 0X00;
|
||||
P1M0 = 0Xff;
|
||||
P1M1 = 0X00;
|
||||
P2M0 = 0Xff;
|
||||
P2M1 = 0X00;
|
||||
P3M0 = 0X00;
|
||||
P3M1 = 0X00;
|
||||
P4M0 = 0Xff;
|
||||
P4M1 = 0X00;
|
||||
P5M0 = 0Xff;
|
||||
P5M1 = 0X00;
|
||||
}
|
||||
|
||||
void Init_Timer()
|
||||
{
|
||||
/****************** Timer 0 Interrupt Setup **********************/
|
||||
AUXR |= 0x80; // Set Timer 0 to 1T mode
|
||||
TMOD = 0x00; // Set Timer 0 to Mode 0 (16-bit auto-reload)
|
||||
TL0 = T1MS; // Initialize timer value
|
||||
TH0 = T1MS >> 8;
|
||||
TR0 = 1; // Start Timer 0
|
||||
ET0 = 1; // Enable Timer 0 interrupt
|
||||
|
||||
/***************** External Interrupt Setup *************************/
|
||||
IT0 = 1; // Set INT0 to falling edge trigger
|
||||
EX0 = 1; // Enable external interrupt INT0
|
||||
IT1 = 1; // Set INT1 to falling edge trigger
|
||||
EX1 = 1; // Enable external interrupt INT1
|
||||
INT_CLKO |= 0x70; // Enable INT2, INT3, INT4 (EX4 = 1, EX3 = 1, EX2 = 1)
|
||||
|
||||
EA = 1; // Enable global interrupts
|
||||
}
|
||||
|
||||
void Array_CLR(uint8 *p)
|
||||
{
|
||||
uint8 i=0;
|
||||
while(i!=16)
|
||||
{
|
||||
p[i] = 0x00;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowScore(uint score)
|
||||
{
|
||||
uint8 i;
|
||||
uint8 qx,bx,sx,gx;
|
||||
qx = score /1000;
|
||||
bx = score %1000 /100;
|
||||
sx = score %100/10;
|
||||
gx = score %10;
|
||||
|
||||
Array_CLR(DispRAM);
|
||||
|
||||
for(i=0;i<5;i++)
|
||||
DispRAM[8-i] = (num[sx][i]<<4) | (num[gx][i]);
|
||||
|
||||
for(i=0;i<5;i++)
|
||||
DispRAM[14-i] = (num[qx][i]<<5) | (num[bx][i]<<1);
|
||||
|
||||
// MatxDisp(DispRAM,duty);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
Port_Init();
|
||||
Sound_Init();
|
||||
Init_Timer();
|
||||
Sound_Tone(1,14,5);// drop
|
||||
|
||||
srand(TL0);
|
||||
delayms(100);
|
||||
Play_Music(sound_game_start);
|
||||
Flash_Screen_Clear();
|
||||
while(1)
|
||||
{
|
||||
tms = 0;
|
||||
keypad = K_NULL;// Clear key status
|
||||
switch (GUI_Main()) // Enter the user game selection interface and return to the selected game.
|
||||
{
|
||||
case 1: Tetris_Game(); break;
|
||||
case 2: Snake_Game(); break;
|
||||
case 3: RAC_Game(); break;
|
||||
case 4: Shot_Game(); break;
|
||||
}
|
||||
Play_Music(sound_game_over);
|
||||
Flash_Screen_Clear();
|
||||
ShowScore(scores); // Load the score into video memory
|
||||
delayms(300);
|
||||
|
||||
keypad = K_NULL;
|
||||
while(keypad != K_UP) // Keep the score displayed when the OK button is not pressed.
|
||||
{
|
||||
MatxDisp(DispRAM,duty);
|
||||
SMG_Display(scores,duty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Timer0 interrupt routine */
|
||||
void T0_Timer_1ms_int() interrupt 1 using 1
|
||||
{
|
||||
if(tms<0xfffe) tms++; // Prevent overflow
|
||||
if(key_state){ if(!--keycont) key_state=0;}
|
||||
|
||||
if(PIN_TR2)// If TR2 is enabled, sound effects will begin playing.
|
||||
{
|
||||
if(!sound_cnt_time--)
|
||||
{
|
||||
TR2_OFF;
|
||||
beep = 1;
|
||||
if(music_p[s_p][1])
|
||||
{
|
||||
Sound_Tone(sound_ON,music_p[s_p][0],music_p[s_p][1]);
|
||||
s_p++; // Automatically load the next note to achieve simultaneous sound effects and gameplay.
|
||||
}
|
||||
}
|
||||
}
|
||||
if(KEY_DOWN==0 & KEY_UP==0) IAP_CONTR=0x60;// Software reset download program
|
||||
}
|
||||
|
||||
void T2_Timer_Sound_freq() interrupt 12 // Interrupt Entry
|
||||
{
|
||||
beep = ~beep; // Buzzer frequency vibration
|
||||
}
|
||||
|
||||
uint8 Get_Kvuale(uint8 key_delay)// Key debouncing processing, parameter is sensitivity adjustment
|
||||
{
|
||||
uint8 kvuale = K_NULL; // The returned initial value is null.
|
||||
if(keypad != K_NULL) // When the key value is not NULL, it means that a key has been pressed.
|
||||
{
|
||||
if(!key_state) // When the button status bit (state) is 0, it indicates that the first trigger is valid; when it is 1, it indicates a repeated trigger.
|
||||
{
|
||||
key_state=1; // Set to 1 to prevent repeated triggering.
|
||||
kvuale = keypad;// Get Read Key Value
|
||||
keycont = key_delay;// Loading debouncing time
|
||||
}
|
||||
keypad = K_NULL; // Clear key value
|
||||
}
|
||||
return kvuale;
|
||||
}
|
||||
/********* External interrupt button area **********/
|
||||
void exint0() interrupt 0 //INT0
|
||||
{
|
||||
keypad = 0;
|
||||
}
|
||||
void exint1() interrupt 2 //INT1
|
||||
{
|
||||
keypad = 1;
|
||||
}
|
||||
void exint2() interrupt 10 //INT2
|
||||
{
|
||||
keypad = 2;
|
||||
}
|
||||
void exint3() interrupt 11 //INT3
|
||||
{
|
||||
keypad = 3;
|
||||
}
|
||||
void exint4() interrupt 16 //INT4
|
||||
{
|
||||
keypad = 4;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user