-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrecord.asm
584 lines (427 loc) · 17.8 KB
/
record.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
.686
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
includelib msvcrt.lib
include masm32.inc
includelib masm32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
strlen PROTO C:dword,:vararg
strcat PROTO C:dword,:dword
strcpy PROTO C:dword,:dword
prepareRankInfo proto
getBestByName proto :dword
InitDataBase proto
saveGame proto :dword, :dword, :dword
loadGame proto :dword
createTable proto
updateBestByName proto :dword, :dword
dword2str proto :dword, :dword
str2dword proto :dword, :dword
messageBox proto :dword, :dword
extern BLOCK:dword
extern rank_info1:dword
extern rank_info2:dword
extern rank_info3:dword
extern rank_info4:dword
extern rank_info5:dword
extern num_score:dword
extern num_highest_score:dword
public saveGame
public loadGame
public initDataBase
public createTable
public prepareRankInfo
public getBestByName
public messageBox
;--------------------------------------------------
;SQLiteÏà¹Øº¯ÊýÖ¸Õ붨Òå
;--------------------------------------------------
sql_open typedef proto :dword,:dword
SQL_Open typedef ptr sql_open
sql_close typedef proto :dword
SQL_Close typedef ptr sql_close
callback typedef proto :dword,:dword,:dword,:dword
CallBack typedef ptr callback
sql_exec typedef proto :dword,:dword,:CallBack,:dword,:dword
SQL_Exec typedef ptr sql_exec
sql_slct typedef proto :dword,:dword,:dword,:dword,:dword,:dword
SQL_Slct typedef ptr sql_slct
;---------------------------------------------------------------------------------
.data
sql_insert2records db 'insert into Records(name, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,score) values', 0
sql_selectByName db 'select * from Records where name = ',0
sql_deleteByName db 'delete from Records where name = ', 0
sql_selectBestByName db 'select best from Players where name = ',0
sql_selectRank db 'select * from Players order by best asc limit 5', 0
sql_updateBestByName db 'update Players set best = ',0
sql_updateBestByName1 db ' where name = ', 0
sql_insertNewPlayer db 'insert into Players(name, best) values', 0
;info of sqlite
libName db 'sqlite3.dll',0
sqlite3_open db 'sqlite3_open',0
sqlite3_close db 'sqlite3_close',0
sqlite3_exec db 'sqlite3_exec',0
sqlite3_slct db 'sqlite3_get_table',0
fileName db 'data.db',0
sql_createTable_Plays db 'create table if not exists Players(name varchar(60),best integer)', 0
sql_createTable_Records db 'create table if not exists Records(id integer primary key autoincrement,name varchar(60), score integer, '
db 'a0 integer, a1 integer, a2 integer, a3 integer, a4 integer, a5 integer, a6 integer, a7 integer, a8 integer, a9 integer, a10 integer, a11 integer, a12 integer, a13 integer, a14 integer, a15 integer)', 0
split db ':',0
endline db 0dh,0ah,0
empty db 0
pad db 5 dup(' '),0
szSave db 'Save successfully!', 0
szSaveTitle db 'Save', 0
;for debug
;states dword 2,16,0,0,16,0,0,0,2,4,8,16,32,1024,2048,0
;sscore dword 4096
;sname db 'Luna', 0
;---------------------
lq db '(', 0
rq db ')', 0
sy db 39, 0
cm db ',', 0
;------------------------------------------------------------------
.data?
str0 db 32 dup(?)
sql db 500 dup(?)
szStr db 600 dup(?)
szStr1 db 500 dup(?)
hInstance1 dd ?
;info of sqlite
hLib dd ?
hDB dd ?
errorInfo dd ?
hs_open SQL_Open ?
hs_close SQL_Close ?
hs_exec SQL_Exec ?
hs_slct SQL_Slct ?
.const
.code
messageBox proc address_content:dword, address_title:dword
invoke MessageBox,NULL, address_content, address_title, MB_OK
ret
messageBox endp
;-------------------------------------------------------------------------------
;prepareRankInfo: prepare the rankinfo1-rankinfo5
;-------------------------------------------------------------------------------
prepareRankInfo proc
local @result,@nRow,@nCol
local @i,@j,@index
invoke hs_open,offset fileName,offset hDB
invoke hs_slct,hDB,offset sql_selectRank,addr @result,addr @nRow,\
addr @nCol,NULL
invoke RtlZeroMemory, offset szStr, sizeof szStr
mov edi,@nCol
mov eax,@nRow
mov @i,eax
mov ebx,@result
.while @i
mov esi,0
.while esi < @nCol
invoke strcat,offset szStr,[ebx + esi*4]
invoke strcat,offset szStr,offset split
invoke strcat,offset szStr,[ebx + edi*4]
invoke strcat,offset szStr,offset pad
inc esi
inc edi
.endw
.if @i == 1
invoke strcpy, offset rank_info1, offset szStr
.elseif @i == 2
invoke strcpy, offset rank_info2, offset szStr
.elseif @i == 3
invoke strcpy, offset rank_info3, offset szStr
.elseif @i == 4
invoke strcpy, offset rank_info4, offset szStr
.elseif @i == 5
invoke strcpy, offset rank_info5, offset szStr
.endif
invoke RtlZeroMemory, offset szStr, sizeof szStr
mov eax,@i
dec eax
mov @i,eax
.endw
;invoke MessageBox,NULL,offset szStr,offset fileName,MB_OK
invoke RtlZeroMemory, offset szStr, sizeof szStr
ret
prepareRankInfo endp
;-------------------------------------------------------------------------------
;updateBestByName: [param1:the address of name; param2:the address of score]
;update the best score in Players where name = NAME.
;-------------------------------------------------------------------------------
updateBestByName proc address_name:dword, address_score:dword
invoke getBestByName, address_name
.if ebx == 1
invoke RtlZeroMemory, offset sql, sizeof sql
invoke strcat, offset sql, offset sql_insertNewPlayer
invoke strcat, offset sql, offset lq
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, address_name
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset cm
invoke RtlZeroMemory, offset str0, sizeof str0
invoke dword2str, address_score, offset str0
;invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset str0
;invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset rq
invoke hs_exec, hDB, offset sql, NULL, NULL, NULL
.else
mov ebx, address_score
.if [ebx]>=eax
invoke RtlZeroMemory, offset sql, sizeof sql
invoke strcat, offset sql, offset sql_updateBestByName
invoke RtlZeroMemory, offset str0, sizeof str0
invoke dword2str, address_score, offset str0
invoke strcat, offset sql, offset str0
invoke strcat, offset sql, offset sql_updateBestByName1
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, address_name
invoke strcat, offset sql, offset sy
invoke hs_exec,hDB,offset sql,NULL,NULL,NULL
.endif
.endif
ret
updateBestByName endp
;------------------------------------------------------------------------------------------------------------------------
;getBestByName: return the best score and error code from Players. if there is a record with name = NAME in Players, error code = 0. Otherwise return the error code 1.
;------------------------------------------------------------------------------------------------------------------------
getBestByName proc address_name:dword
local @result,@nRow,@nCol
local @i,@j,@index
LOCAL @best:dword
local @flag:dword
; 5 30
invoke hs_open,offset fileName,offset hDB
mov @best, 0
mov @flag, 0
invoke RtlZeroMemory, offset sql, sizeof sql
invoke strcat, offset sql, offset sql_selectBestByName
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, address_name
invoke strcat, offset sql, offset sy
mov eax, offset sql
invoke hs_slct,hDB,offset sql,addr @result,addr @nRow,\
addr @nCol,offset errorInfo
invoke RtlZeroMemory, offset szStr, sizeof szStr
mov edi,@nCol
mov eax,@nRow
mov @i,eax
mov ebx,@result
.while @i
mov esi,0
.while esi < @nCol
mov ecx, offset szStr
invoke strcat,offset szStr,[ebx + edi*4]
invoke str2dword, offset szStr, addr @best
mov @flag, 1
inc esi
inc edi
.endw
mov eax,@i
dec eax
mov @i,eax
.endw
invoke RtlZeroMemory, offset szStr, sizeof szStr
mov eax, @best
.if @flag == 1
mov ebx, 0
.else
mov ebx, 1
.endif
ret
getBestByName endp
str2dword proc uses eax ebx ecx edx address_str:dword, address_num:dword
local @n:dword
LOCAL @len:dword
LOCAL @str:byte
invoke strlen, address_str
mov @len, eax
mov @n, 0
getNum:
mov eax, address_str
add eax, @n
mov bl, [eax]
mov @str, bl
mov eax, address_num
mov ebx, [eax]
mov eax, 10
mul ebx ; result in edx:eax
mov ebx, eax
xor eax, eax
mov al, @str
sub al, '0'
add ebx, eax
mov eax, address_num
mov [eax], ebx
inc @n
mov eax, @len
cmp @n, eax
jl getNum
ret
str2dword endp
dword2str proc uses eax ebx ecx edx address_num:dword, address_str:dword
local @num:dword
local @n:dword
mov @n, 0
mov eax, address_num
mov ebx, [eax]
mov @num, ebx
divNum:
xor edx, edx
mov eax, @num
mov ebx, 10
div ebx ; quotient in eax while remainder in edx
push edx ; remainder
mov @num, eax ; update numerator
inc @n ; update n
cmp eax, 0
jnz divNum
mov ecx, @n
mov ebx, 0
getNum:
pop eax
add al, '0'
mov ebx, address_str
mov [ebx], al
add address_str, 1
loop getNum
mov ebx, address_str
mov byte ptr[ebx], 0
mov eax, 0
ret
dword2str endp
saveGame proc address_states:dword, address_name:dword, address_score:dword
local @i:dword
invoke hs_open,offset fileName,offset hDB
invoke RtlZeroMemory, offset sql, sizeof sql
invoke strcat, offset sql, offset sql_deleteByName ; delete first. TODO: more save_file?
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, address_name
invoke strcat, offset sql, offset sy
invoke hs_exec, hDB, offset sql, NULL, NULL, NULL
invoke RtlZeroMemory, offset sql, sizeof sql
invoke strcat, offset sql, offset sql_insert2records
invoke strcat, offset sql, offset lq
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, address_name
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset cm
writeStates:
mov @i, 0
.while @i<16
mov ebx, address_states
invoke RtlZeroMemory, offset str0, sizeof str0
invoke dword2str, ebx, offset str0
;invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset str0
;invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset cm
add address_states, 4
inc @i
;loop writeStates
.endw
invoke RtlZeroMemory, offset str0, sizeof str0
invoke dword2str, address_score, offset str0
;invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset str0
;invoke strcat, offset sql, offset sy
invoke strcat, offset sql, offset rq
invoke hs_exec, hDB, offset sql, NULL, NULL, NULL
invoke RtlZeroMemory, offset sql, sizeof sql
invoke updateBestByName, address_name, address_score
invoke MessageBox,NULL,offset szSave,offset szSaveTitle,MB_OK
ret
saveGame endp
;-------------------------------------------------------------------------------------------------------------
;loadGame[param1:the address(dword) of name(byte) return 0 when no error occurs.]
;set the value of BLOCK, num_score
;return 0 if loadGame ok.
;-------------------------------------------------------------------------------------------------------------
loadGame proc address_name:dword
local @result,@nRow,@nCol
local @i,@j,@index
LOCAL @iBlock:dword
LOCAL @error:dword
invoke RtlZeroMemory, offset num_highest_score, sizeof num_highest_score
invoke RtlZeroMemory, offset num_score, sizeof num_score
; first set num_best_score
invoke getBestByName, address_name
mov num_highest_score, eax
mov @error, ebx
invoke RtlZeroMemory, offset sql, sizeof sql
invoke strcat, offset sql, offset sql_selectByName
invoke strcat, offset sql, offset sy
invoke strcat, offset sql, address_name
invoke strcat, offset sql, offset sy
invoke hs_open,offset fileName,offset hDB
mov eax, offset szStr
invoke hs_slct,hDB,offset sql,addr @result,addr @nRow,\
addr @nCol,offset errorInfo
invoke strcpy,offset szStr, offset empty
;mov @str,eax
mov edi,@nCol
mov eax,@nRow
mov @i,eax
mov ebx,@result
.while @i
mov esi,0
.while esi < @nCol
invoke strcpy,offset szStr,[ebx + edi*4]
.if esi == 0 ; id
.elseif esi == 1 ; name
.elseif esi == 2 ; score
invoke str2dword, offset szStr, offset num_score
.else
mov @iBlock, esi
sub @iBlock, 3
;invoke RtlZeroMemory, addr BLOCK[@iBlock], sizeof BLOCK[@iBlock]
mov ecx, offset BLOCK
push eax
mov eax, 4
mul @iBlock
add ecx, eax
pop eax
invoke str2dword, offset szStr, ecx
.endif
inc esi
inc edi
invoke RtlZeroMemory, offset szStr, sizeof szStr
.endw
mov eax,@i
dec eax
mov @i,eax
.break ; TODO: can we get more save_file?
.endw
mov eax, @error
ret
loadGame endp
createTable proc
invoke hs_open,offset fileName,offset hDB
invoke hs_exec,hDB,offset sql_createTable_Plays,NULL,NULL,NULL
invoke hs_exec,hDB,offset sql_createTable_Records,NULL,NULL,NULL
ret
createTable endp
initDataBase proc
invoke LoadLibrary,offset libName
mov hLib,eax
invoke GetProcAddress,hLib,addr sqlite3_open
mov hs_open,eax
invoke GetProcAddress,hLib,addr sqlite3_close
mov hs_close,eax
invoke GetProcAddress,hLib,addr sqlite3_exec
mov hs_exec,eax
invoke GetProcAddress,hLib,addr sqlite3_slct
mov hs_slct,eax
;invoke hs_open,offset fileName,offset hDB
;invoke hs_exec,hDB,offset sql_createTable_Plays,NULL,NULL,NULL
;invoke hs_exec,hDB,offset sql_createTable_Records,NULL,NULL,NULL
ret
initDataBase endp
end