All pastes #517605 Raw Edit

Anonymous

public c v1 · immutable
#517605 ·published 2007-05-29 02:38 UTC
rendered paste body
#include "../devkitARM/arm-elf/include/math.h"#include "../tonc_code_/code/tonclib/tonc_gba.h"#include "./gfx/test.h"#include "./gfx/font.h"#include "./snd/Sound.h"#include "./posprintf.h"#define RGB8(r,g,b)	( (((b)>>3)<<10) | (((g)>>3)<<5) | ((r)>>3) )#define TETR_O 0  //Pieces#define TETR_S 1#define TETR_Z 2#define TETR_I 3#define TETR_T 4#define TETR_L 5#define TETR_J 6#define STANDARD 0 //Drop types#define FIRM 1#define SOFT 2#define DAS 12 //Frame values, may use variable system in the future#define ARE 18#define LOCK 30#define CLEAR 30#define ROLLS 6 //Number of piece rolls before allowing use of piece in history#define R 0#define G 1#define B 2#define FONTBASE 9#define GAMEPAK_RAM  ((u8*)0x0E000000)u8 *Save = GAMEPAK_RAM;//-------------------------tables-------------------------const int block_x[7][4][4] = {	{{1,2,1,2},{1,2,1,2},{1,2,1,2},{1,2,1,2},}, //O	{{0,1,1,2},{1,1,2,2},{0,1,1,2},{1,1,2,2},}, //S	{{2,1,1,0},{1,1,0,0},{2,1,1,0},{1,1,0,0},}, //Z	{{0,1,2,3},{1,1,1,1},{0,1,2,3},{1,1,1,1},}, //I	{{0,1,2,1},{1,0,1,1},{1,0,1,2},{1,2,1,1},}, //T	{{0,1,2,0},{0,1,1,1},{2,0,1,2},{1,1,1,2},}, //L	{{0,1,2,2},{0,1,1,1},{0,0,1,2},{1,1,1,2},}, //J};const int block_y[7][4][4] = {	{{1,1,2,2},{1,1,2,2},{1,1,2,2},{1,1,2,2},}, //O	{{1,1,2,2},{1,2,0,1},{1,1,2,2},{1,2,0,1},}, //S	{{1,1,2,2},{1,2,0,1},{1,1,2,2},{1,2,0,1},}, //Z - same as S, change made in block_x	{{1,1,1,1},{0,1,2,3},{1,1,1,1},{0,1,2,3},}, //I	{{1,1,1,2},{0,1,1,2},{1,2,2,2},{0,1,1,2},}, //T	{{1,1,1,2},{0,0,1,2},{1,2,2,2},{0,1,2,2},}, //L	{{1,1,1,2},{2,0,1,2},{1,2,2,2},{2,1,0,0},}, //J};const int colors[7][3] = {	{255,255,0,},{0,255,0,},{255,0,0},{0,255,255,},{191,0,255,},{255,127,0,},{0,0,255,},};const float CGrav[15] = {0.125f, 0.25f, .5f, .75f, 1.0f, 1.2f, 1.8f, 2.0f, 2.4f, 3.0f, 4.0f, 5.0f, 6.0f, 8.0f, 20.0f};const float MStartGrav[5] = {1.0f/64.0f, 1.0f/3.5f, 1/64.0f, 2.0f, 5.0f};const float MEndGrav[5] = {1.0f/3.5f, 1.0f/1.8f, 1.0f, 4.0f, 3.0f};const int ClassReq[20] = {0, 400, 800, 1400, 2000, 3500, 5500, 8000, 12000,							16000, 22000, 30000, 40000, 52000, 66000, 82000,							100000, 120000, 126000, 1000000};//----------------------game text-------------------------const char m_Modes[17][8] = {"Master \0",							"Accel. \0",							".125 G \0",							".25 G  \0",							".50 G  \0",							".75 G  \0",							"1.0 G  \0",							"1.2 G  \0",							"1.8 G  \0",							"2.0 G  \0",							"2.4 G  \0",							"3.0 G  \0",							"4.0 G  \0",							"5.0 G  \0",							"6.0 G  \0",							"8.0 G  \0",							"20  G  \0",};const char Class[19][4] = {"9 \0",							"8 \0",							"7 \0",							"6 \0",							"5 \0",							"4 \0",							"3 \0",							"2 \0",							"1 \0",							"S1\0",							"S2\0",							"S3\0",							"S4\0",							"S5\0",							"S6\0",							"S7\0",							"S8\0",							"S9\0",							"GM\0",};//----------------------global variables-------------------------struct {int tx; int ty; int rot; int type;		int vr; int vx; int prev_vx; int vy;		int das; float drop; int lock;		int clear; int live;		int lines; int level; int mode;		int score; int curr_lines; int row_forced; int combo;		int bravo;		int rank; int GM_Req;} P;int history[4];int are;int playfield[10][23];int timer[3];int counter;int frames;BGINFO bg0;typedef struct _SOUND_CHANNEL{   s8 *data;       // pointer to the raw sound data in ROM (0 for inactive channel)   u32 pos;        // current position in the data (20.12 fixed-point)   u32 inc;        // increment (20.12 fixed-point)   u32 vol;        // volume (0-64, sort of 1.6 fixed-point)   u32 length;     // length of the whole sound (20.12 fixed-point)   u32 loopLength; // length of looped portion (20.12 fixed-point, 0 for no loop)} SOUND_CHANNEL;typedef struct _SOUND_VARS{   s8 *mixBufferBase;   s8 *curMixBuffer;   u32 mixBufferSize;   u8 activeBuffer;} SOUND_VARS;extern SOUND_VARS soundVars; extern SOUND_CHANNEL channel[4];//----------------------function definitions-------------------------void GfxInit();void VarInit();void BgClear();void Title();void Menu();void PrepGame();void BgHudSetup();void ReadyGo();void GameLoop();void Pause();void GameOver();void WaitForConfirmation();void Timer();void PieceControl(int in_are);void MoveTetrimino(int in_are);float GMaster(int level);void ApplyGravity();void LockTetrimino();void ClearLine(int line);void CueTetrimino();int RandTetrimino(int first);void CheckLoss();int CollideTetrimino(int x, int y, int r);void DispTetrimino();void DispPlayfield();void DispNext();void DispHud();int DimColor(int color, float dim);void GfxUpdate();void SramSaveInt(int val, int pos);int SramLoadInt(int pos);//***************************************************************/*int rand(int max){	seed++;    seed *= 69069;    return (unsigned int)(seed) % max;}*/#define RAND_A 1588635695#define RAND_R 1117695901 /*  linear congruential generator.  GBA tuning by Clifton Cline (phirewind)*/u32 seed = 93186752;u32 random_seed_vbl = 93186752; // Seed the generatorvoid rand_seed (u32 init){    if (init != 0)        seed = init;}// return a random number from 0 to nu16 rand (u16 n){    // generate a new 32-bit seed    seed = RAND_A * ( seed & 1 ) - RAND_R * ( seed >> 1 );       // apply the new seed to the range (n)    return ( n * (seed >> 16) ) >> 16;} char string[32];int convert(conv){  if((conv >= 'a') && (conv <= 'z'))	  conv -= 32;  if((conv >= 'A') && (conv <= 'Z'))    return conv - 0x41 + FONTBASE;  else if((conv >= '0') && (conv <= '9'))    return conv - '0' + 26 + FONTBASE;  else if(conv == '-')    return conv - '-' + 36 + FONTBASE;	else if(conv == '.')    return conv - '.' + 37 + FONTBASE;  else    return 0;}void draw_string(int str_x, int str_y, const char *msg){	int i;	int offset = str_x + str_y * 32;	for (i = 0; msg[i] != 0; ++i)	  bg0.map[offset + i] = convert(msg[i]);}int frames_this = 1, frames_last, vsyncs_this;void DispFps(){    posprintf(&string[0], "%02d", frames_last);    draw_string(28,18, &string[0]);	posprintf(&string[0], "%02d", vsyncs_this);    draw_string(28,19, &string[0]);}void fps(){	rand_seed(random_seed_vbl++);    vsyncs_this++;	if(vsyncs_this >= 60){	  frames_last = frames_this;	  frames_this = 0;	  vsyncs_this = 0;}    REG_IF |= IF_VBLANK;}void SetFpsInterrupt(){    REG_INTMAIN= fps;    REG_DISPSTAT |= DSTAT_VBL_IRQ;    REG_IE |= IF_VBLANK;    REG_IME= 1;}//***************************************************************int screen = 0;int main(){	GfxInit();	SoundInit();	SetFpsInterrupt();	void (*CurrentAction)();	while(1){		vid_vsync();		SoundVsync();		frames_this++;		key_poll();		if(key_is_down(KEY_RESET) == KEY_RESET){			BgClear();			int i;			for(i = 0; i < 4; i++){				oe_set_pos(&oe_buffer[i], 240, 160);				SoundStop(i);}			screen = 0;}		switch(screen){			case 0:				CurrentAction = Title;				break;			case 1:				CurrentAction = Menu;				break;			case 2:				CurrentAction = PrepGame;				break;			case 3:				CurrentAction = ReadyGo;				break;			case 4:				CurrentAction = GameLoop;				break;			case 5:				CurrentAction = GameOver;				break;			case 6:				CurrentAction = Pause;				break;		}		CurrentAction();		DispFps();		GfxUpdate();	}}//******************************************************************//******************************************************************//******************************************************************void GfxInit(){	int i;	dma_memcpy(&tile_mem[CBB_OBJ][0], testTiles, testTilesLen);  //copy gfx	dma_memcpy(&tile_mem[0][0], testTiles, testTilesLen);	dma_memcpy(&tile_mem[0][(FONTBASE<<1)], fontTiles, fontTilesLen);	dma_memcpy(pal_obj_mem, testPal, testPalLen);	dma_memcpy(pal_bg_mem, testPal, testPalLen);	oam_init();		for(i = 0; i < 7; i++)		pal_bg_mem[i + 1] = DimColor(i, .7);		//pal_bg_mem[i] = testPal[16 + i];	REG_DISPCNT = DCNT_OBJ_ON | DCNT_OBJ_1D | _DCNT_MODE0 | DCNT_BG0_ON;  //set modes	for(i = 0; i < 4; i++){	  oe_set_attr(&oe_buffer[i], (_OE_A0_SQUARE | OE_A0_256C),		  _OE_A1_SIZE_8,		  2);	  oe_set_pos(&oe_buffer[i], 240, 160);}		bg_init(&bg0, 0, 0, 2, (_BG_REG_S32 | BG_256C));	bg_set_pos(&bg0, 0, 0);}void VarInit(){	counter = 0;	P.live = 1; P.lines = 0; P.level = 0; P.score = 0;	P.das = 0; P. clear = 0; P.curr_lines = 0; P.row_forced = 0; P.combo = 1;	P.bravo = 1;	P.rank = 0; P.GM_Req = 0;		int i, ii;	for(i = 0; i < 3; i++)		timer[i] = 0;	for(i = 0; i < 10; i++)		for(ii = -3; ii < 20; ii++)			playfield[i][ii + 3] = 0;	int x = TETR_Z;	for(i = 0; i < 4; i++){		history[i] = x;		x ^= TETR_S;}	while(RandTetrimino(1));	for(i = 0; i < 3; i++)		RandTetrimino(0);		CueTetrimino();}void BgClear(){	int i;	for(i = 0; i < 32 * 32; i++)		bg0.map[i] = 0;}void Title(){	BgClear();	int i;	for(i = 0; i < 4; i++){		oe_set_pos(&oe_buffer[i], 240, 160);		SoundStop(i);}	//seed = SramLoadInt(0);	posprintf(&string[0], "tetris grand master");	draw_string(0,0,&string[0]);	posprintf(&string[0], "wip clone");	draw_string(0,1,&string[0]);	posprintf(&string[0], "speed select");	draw_string(0,3,&string[0]);	P.mode = 0;	screen = 1;}void Menu(){		posprintf(&string[0], "%s", &m_Modes[P.mode][0]);		draw_string(1,4,&string[0]);		if(key_hit(KEY_RIGHT))			P.mode++;		else if(key_hit(KEY_LEFT))			P.mode--;		if(P.mode < 0)			P.mode = 16;		P.mode %= 17;		if(key_hit(KEY_A|KEY_START))			screen = 2;}void PrepGame(){		BgClear();		BgHudSetup();		VarInit();		screen = 3;}void BgHudSetup(){	int i;	for(i = 10; i < 32 * 20; i += 32)		bg0.map[i] = 8;	posprintf(&string[0], "next");	draw_string(12,0,&string[0]);		posprintf(&string[0], "lines");	draw_string(19,0,&string[0]);	posprintf(&string[0], "level");	draw_string(19,3,&string[0]);	posprintf(&string[0], "---");	draw_string(19,5,&string[0]);	posprintf(&string[0], "points");	draw_string(19,9,&string[0]);	posprintf(&string[0], "rank");	draw_string(12,12,&string[0]);		posprintf(&string[0], "rank up at");	draw_string(12,15,&string[0]);}void ReadyGo(){	DispTetrimino();	counter++;		if(counter < 60)			posprintf(&string[0], "ready?");		else if(counter < 120)			posprintf(&string[0], " go   ");		else{			posprintf(&string[0], "      ");			screen = 4;}		draw_string(2,10,&string[0]);}void GameLoop(){	if(key_hit(KEY_START))		screen = 6; //simple abuseable pause, will be replaced later	Timer();	if((!are)&&(!P.clear)){		PieceControl(are);		MoveTetrimino(are);		DispTetrimino();	}	if(P.clear){		if(P.clear == 1){			SoundPlay(&LINE_CLEAR_DATA, LINE_CLEAR_LENGTH, 18157, 1, 64);			P.score += ((int)(((P.level + P.curr_lines)/4) + 0.5f) + P.row_forced) * P.curr_lines * P.combo * P.bravo;			if(P.score > 999999)				P.score = 999999;}		if(P.clear == CLEAR - 1)			SoundPlay(&LINE_DROP_DATA, LINE_DROP_LENGTH, 18157, 2, 64);		if(P.score > ClassReq[P.rank + 1]){			P.rank++;			if(P.rank == 8)				if(P.level < 300)					P.GM_Req++;			if(P.rank == 12)				if(P.level < 500)					P.GM_Req++;			if(P.rank == 17)				P.GM_Req++;}			//The last GM condition is that the player reach level 999 before 13:30:00, which is checked in Game Over.		P.clear++;		P.clear %= CLEAR;	}	else if(are){		if(are == 1)			CueTetrimino();		if(are == ARE - 1){			CheckLoss();			MoveTetrimino(are);			}		PieceControl(are);		are++;		are %= ARE;	}	if(!P.clear)		DispPlayfield();	if(P.level >= 999){		P.level = 999;		P.live = 0;}	DispHud();	if(!P.live)		screen = 5;	//SramSaveInt(seed, 0);}void Pause(){	if(key_hit(KEY_START))		screen = 4;}void GameOver(){	posprintf(&string[0], "game over");	draw_string(20,12,&string[0]);	if(P.level == 999){		if(P.GM_Req == 3)			if(timer[2] * 60 + timer[1] < 810){				P.rank++;				DispHud();}		posprintf(&string[0], "all clear");		draw_string(20,12,&string[0]);}	if(key_hit(KEY_START))		screen = 0;	}void Timer(){	timer[0]++;	if(timer[0] >= 60){		timer[1]++;		timer[0] = 0;}	if(timer[1] >= 60){		timer[2]++;		timer[1] = 0;}}//******************************************************************//******************************************************************//******************************************************************void PieceControl(int in_are){	u16 (*key_are)(u16 key);	if(in_are)		key_are = key_is_down;	else key_are = key_hit;	if(key_are(KEY_B))		P.vr = -1;	else if(key_are(KEY_A))		P.vr = 1;	else P.vr = 0;	P.prev_vx = P.vx;	if(key_is_down(KEY_LEFT))		P.vx = -1;	else if(key_is_down(KEY_RIGHT))		P.vx = 1;	else P.vx = 0;	if(P.prev_vx == P.vx)		if(P.das < DAS)			P.das++;		else;	else P.das = 0;		if(!in_are){		if(key_hit(KEY_UP))			P.vy = FIRM;		else if(key_is_down(KEY_DOWN))			P.vy = SOFT;		else P.vy = STANDARD;}}void MoveTetrimino(int in_are){	if(!in_are){		if(P.vx)			if((P.das == 0)||(P.das == DAS))				if(!CollideTetrimino(P.tx + P.vx, P.ty, P.rot))					P.tx += P.vx;}	int i = 1, ii = 0;	if(P.vr)		while(ii < 3){			if(!CollideTetrimino((P.tx + (i - 1)), P.ty, P.rot + P.vr)){				P.rot += P.vr;				P.rot &= 3;				P.tx += (i - 1);				if(in_are)					SoundPlay(&ARE_ROT_DATA, ARE_ROT_LENGTH, 18157, 0, 64);				ii = 4;}			if(in_are)				break;			i++; i %= 3;			ii++;			if((P.type == TETR_I)||(P.type == TETR_O))				break;			if((P.type == TETR_L)||(P.type == TETR_J))				if(P.rot == 0)					if(playfield[P.tx + 1][P.ty + 1])						break;			if(P.type == TETR_T)				if(P.rot == 2)					if(playfield[P.tx + 1][P.ty])						break;		}	if(!P.mode)		P.drop += GMaster(P.level);	else if(P.mode == 1)		P.drop += ((float)(P.level + 1)/60.0f);	else P.drop += CGrav[P.mode - 2];	if(!in_are){		if(P.vy == FIRM){			while(!CollideTetrimino(P.tx, P.ty + 1, P.rot)){				P.lock = 0;				P.ty++;			    P.row_forced++;}}		else if(P.vy == SOFT){			if(P.drop < 1){				P.drop = 1;				P.row_forced++;}			P.lock = 254;}		ApplyGravity();}}float GMaster(int level){	int lv_mod, ramp = 0, set = 0;	float g;	lv_mod = level % 100;	ramp = (int)(lv_mod/10);           	set = (int)(level/100);		if(set < 2){		ramp = (ramp>>1);	}	if(set > 4)		return 20;	g = (float)(((MStartGrav[set] * (float)((10 - ramp)/10.0f)) + (MEndGrav[set] * (float)((ramp)/10.0f))));	return g;}void ApplyGravity(){	if(!CollideTetrimino(P.tx, P.ty + 1, P.rot)){		if(P.drop >= 1){			pal_obj_mem[P.type + 1] = DimColor(P.type, 1);			P.lock = 0;			P.drop--;			P.ty++;			ApplyGravity();}}	else{		pal_obj_mem[P.type + 1] = DimColor(P.type, .5 + (.5 * ((float)LOCK - P.lock)/(float)LOCK));		P.lock++; P.drop = 0;		if(P.lock == 1)			SoundPlay(&COLLIDE_DATA, COLLIDE_LENGTH, 18157, 1, 64);}	if(P.lock > LOCK)		LockTetrimino();}void LockTetrimino(){	are = 1;	int i, ii, clear;	for(i = 0; i < 4; i++)		playfield[P.tx + block_x[P.type][P.rot][i]]					[P.ty + block_y[P.type][P.rot][i] + 3] = P.type + 1;		for(i = 0; i < 20; i++){			clear = 1;			for(ii = 0; ii < 10; ii++)				if(!playfield[ii][i + 3]){					clear = 0; ii = 11;}			if(clear){				ClearLine(i);				P.curr_lines++;}		}	if(P.curr_lines){		for(i = 0; i < 10; i++)			for(ii = 0; ii < 20; ii++)				if(!playfield[i][ii + 4])					P.bravo = 4;				else{P.bravo = 1; break;}		P.combo = (P.combo - 1) + ((P.curr_lines<<1) - 1);}	else P.combo = 1;	//DispPlayfield();	SoundPlay(&SET_DATA, SET_LENGTH, 18157, 2, 64);	int mod;	if(P.level < 900)		mod = 99;	else mod = 98;	if(P.level % 100 != mod)		P.level++;	P.tx = 30;	P.ty = 30;	for(i = 0; i < 4; i++){	  oe_set_attr(&oe_buffer[i], (_OE_A0_SQUARE | OE_A0_256C),		  _OE_A1_SIZE_8,		  0);	  oe_set_pos(&oe_buffer[i], 240, 160);	dma_memcpy(pal_obj_mem, testPal, testPalLen);}}void ClearLine(int line){	int i, ii;	for(i = 0; i < 10; i++)		playfield[i][line + 3] = 0;	for(i = 0; i < 10; i++)		playfield[i][0] = 0;	DispPlayfield();	for(i = line; i >= -2; --i)		for(ii = 0; ii < 10; ii++)			playfield[ii][i + 3] = playfield[ii][i + 2];	P.lines++; P.clear = 1;	P.level++;}int CollideTetrimino(int x, int y, int r){	int i, collision = 0;	for(i = 0; i < 4; i++)		if(!(y + block_y[P.type][(r&3)][i] < 0))			if(playfield[x + block_x[P.type][(r&3)][i]]						[y + block_y[P.type][(r&3)][i] + 3]){							collision = 1; i = 5;}	if(!collision)		for(i = 0; i < 4; i++){			if((x + block_x[P.type][(r&3)][i] < 0)||(x + block_x[P.type][(r&3)][i] > 9)){				collision = 1; i = 5;}			//else if((y + block_y[P.type][(r&3)][i] < 0)||(y + block_y[P.type][(r&3)][i] > 19))  //Okay, so apparently you can rotate out of the upper bound. My bad.			else if(y + block_y[P.type][(r&3)][i] > 19){				collision = 1; i = 5;}}	return collision;}void CueTetrimino(){	P.tx = 3;   //standard tile positions for entering tetrimino	P.ty = -1; //This works until IRS is implemented	P.rot = 0;	P.lock = 0;	P.curr_lines = 0;	P.row_forced = 0;	P.type = history[0];	RandTetrimino(0);	DispNext();}int RandTetrimino(int first){	int i, ii, piece, used;	for(i = 0; i < ROLLS; i++){		used = 0;		piece = rand(7)%7;		for(ii = 0; ii < 4; ii++)			if(history[ii] == piece){				used = 1; ii = 5;}		if(!used)			i = ROLLS + 1;}	if(first)		if((piece == TETR_S)||(piece == TETR_Z)||(piece == TETR_O))			return 1;	for(i = 0; i < 4; i++)		history[i] = history[i + 1];	history[3] = piece;		return 0;}void CheckLoss(){	if(CollideTetrimino(P.tx, P.ty, P.rot)){			LockTetrimino();			GfxUpdate();			P.live = 0;}}void DispTetrimino(){	int i;	for(i = 0; i < 4; i++){      oe_set_pos(&oe_buffer[i], ((P.tx + block_x[P.type][P.rot][i])<<3),								((P.ty + block_y[P.type][P.rot][i])<<3));	  oe_buffer[i].attr2 = ((P.type + 1)<<1)&OE_A2_ID_MASK;}}void DispPlayfield(){	int i, ii;	for(i = 0; i < 10; i++)		for(ii = 0; ii < 20; ii++)			bg0.map[i + ii * 32] = playfield[i][ii + 3];	for(i = 0; i < 10; i++)		for(ii = 0; ii < 3; ii++)			bg0.map[(i + 11) + (ii + 17) * 32] = playfield[i][ii];}void DispNext(){	int i, ii, iii;	for(iii = 0; iii < 3; iii++){	for(i = 0; i < 4; i++)		for(ii = 0; ii < 4; ii++)			bg0.map[(i + 12 + ((iii || 0)<<1)) + (ii + (iii * 3) + 1) * 32] = 0;	for(i = 0; i < 4; i++)		bg0.map[(block_x[history[iii]][0][i] + 12  + ((iii || 0)<<1)) + 		(block_y[history[iii]][0][i] + (iii * 3) + 1) * 32] = history[iii] + 1;}}void DispHud(){	posprintf(&string[0], "%d", P.lines);	draw_string(19,1,&string[0]);	posprintf(&string[0], "%03d", P.level);	draw_string(19,4,&string[0]);	int set;	set = (((int)(P.level/100)+1)*100);	if(set == 1000)		set--;	posprintf(&string[0], "%03d", set);	draw_string(19,6,&string[0]);	posprintf(&string[0], "%6d", P.score);	draw_string(19,10,&string[0]);		posprintf(&string[0], "%s", Class[P.rank]);	draw_string(13,13,&string[0]);	posprintf(&string[0], "%d", ClassReq[P.rank + 1]);	draw_string(13,16,&string[0]);	posprintf(&string[0], "%02d.%02d.%02d", timer[2],timer[1],timer[0]);	draw_string(12,19,&string[0]);}int DimColor(int color, float dim){	return RGB8((int)(colors[color][R]*dim), (int)(colors[color][G]*dim), (int)(colors[color][B]*dim));}void GfxUpdate(){	oe_update(0, 4);	bg_update(&bg0);}void SramSaveInt(int val, int pos){	int i;	for(i = 0; i < 4; i++)		Save[(pos<<2)+i] = (val>>(i<<3))&255;}int SramLoadInt(int pos){	int val, i;	for(i = 0; i < 4; i++)		val |= ((Save[(pos<<2)+i])<<(i<<3));	return val;}